/* $Header: p_init.c,v 2.2 01/10/02 10:27:50 przybyls Exp $ */


/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME:  p_init.c                                              */
/* ============                                                        */
/*                                                                     */
/* Author:                                                             */
/*                                                                     */
/* MODULE PURPOSE:                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/


#include <typedefs.h>
#include <error.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <i_op.h>
#include <p_status.h>
#include <list_mgmt.h>
#include <iomap.h>
#include <zone_config.h>
#include <ramps.h>         /* needed for status.h */
#include <zone_status.h>
#include <status.h>  /* pull in PF_Reset */
#include <pcb_defs.h>

#ifndef DOS
#include <regs.h>

#include <zone_ui.h>
#include <oven.h>  /* to get DetermineInstConfig proto */
#include <detector.h>
#endif

#include <exception.h>
#include <err_handler.h>
#include <keyboard.h>
#include <det_ui.h>


static void     GetEepromCPFLabels (void);
static void     GetEepromCPFControls (void);
static void     GetEepromCPFThermal (void);
static U_INT16  UpdateAuxProm( U_INT8 modul , U_INT16 versn);

/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/

#include "proto.h"
#include "pneu_int.h"

/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/


/*****************************/
/*   STATIC VARIABLES        */
/*****************************/

/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/




/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 ModuleExists( U_INT16 module )

/**end_proto**/
{

    U_INT16 presence;


     if ( ReadEeprom( module, TYPE, &presence ) )
     {
             /* pcb2 returns ffff for an uninstalled module */
             /* dirtball returns a 0000                     */
             /* any valid module will return something else */
             /* neither of these represent a valid type     */

          if (( presence != 0xFFFF ) && ( presence != 0x0000 ))
          {
               if ( ReadEeprom( module, VERSION, &presence ) )
               {
                  if ( (((presence & 0xff00 ) >> 8 ) >= 0x01 ) &&
                       (((presence & 0xff00 ) >> 8 ) <  0xff ) ) return TRUE;
               }
          }
     }

     return FALSE;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 ReadModuleType( U_INT16 module, U_INT16 *type )

/**end_proto**/
{

     U_INT16 x;


     if ( ! ReadEeprom( module, TYPE, &x ) )
     {
          return FALSE;
     }

     *type =  x;

     return TRUE;

}

/**begin_proto**/

BIT8 ReadModuleVersion( U_INT16 module, U_INT16 *version )

/**end_proto**/
{

     U_INT16 x;


     if ( ! ReadEeprom( module, VERSION, &x ) )
     {
          return FALSE;
     }

     *version = (U_INT16) x;

     return TRUE;

}

/**begin_proto**/

BIT8 ValidModuleCksum( U_INT16 module )

/**end_proto**/
{

     U_INT16 x;


     if ( ! ReadEeprom( module, CHECKSUM, &x ) )
     {
          return FALSE;
     }

     if ( x == 0xa5a5 ) return TRUE;
//Inst_Status.Pneu.Module_Cksums[ module ] = 0xbc4d;
printf("ValidModuleCksum:Module_Cksums[ module ] = %04x\n,x=%04x\n",Inst_Status.Pneu.Module_Cksums[ module ],x);
     if ( Inst_Status.Pneu.Module_Cksums[ module ] == x ) return TRUE;
     else                                                 return FALSE;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ReadSensorRange( U_INT8 module, U_INT8 sensor_position, U_INT16 *sensor_range )

/**end_proto**/
{
     U_INT16 range;

     if (  ReadEeprom( module, PS_RANGE+sensor_position-1, &range ) && ( range > 0 ) && ( range < 0xffff) )
     {
          *sensor_range = range;
     }
     else
     {
          *sensor_range = INVALID_PS_RANGE;
     }

}


/**begin_proto**/

void ReadPresScaling( U_INT8 module, U_INT8 position, U_INT16 *dcm2_per_iu )

/**end_proto**/
{
     U_INT16 range;

     if ( ReadEeprom( module, P_SCALING+position-1, &range ) && ( range > 0 ) && ( range <= 320 ))
     {
          *dcm2_per_iu = range;
     }
     else
     {
          *dcm2_per_iu = INVALID_PS_SCALE;
     }

}


void DoAPSensor( U_INT8 module, U_INT8 position, U_INT16 *range, U_INT16 *scaling, U_INT32 *r_dcm2 )
{
     ReadSensorRange( module, position, range );
     ReadPresScaling( module, position, scaling );

     if (( *range != INVALID_PS_RANGE ) && ( *scaling != INVALID_PS_SCALE ))
     {
         *r_dcm2 = (U_INT32)(*range) * (*scaling);
     }
     else
     {
         *r_dcm2 = 0;
     }
}


/**begin_proto**/

void ReadFlowScaling( U_INT8 module, U_INT8 position, U_INT32 *iu_scaling )

/**end_proto**/
{
     U_INT16 range;

     if (( ReadEeprom( module, F_SCALING+position-1, &range ) && (range > 0 ) && ( range < 32 )))
     {
         *iu_scaling = (U_INT32)1 << range;
     }
     else
     {
         *iu_scaling = INVALID_FS_SCALE;
     }

}

/**begin_proto**/

void ReadPurgeFlowScaling( U_INT8 module, U_INT32 *iu_scaling )

/**end_proto**/
{
     U_INT16 range;

      /* spr is always the last logical position */

     if ( ReadEeprom( module, F_SCALING+3-1, &range ) && (range > 0 ) && ( range < 32) )
     {
          *iu_scaling = (U_INT32)1 << range;
     }
     else
     {
          *iu_scaling = INVALID_SPR_SCALE;
     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void GetNlGainQualifiers( U_INT8 module, U_INT16 type, GAS_TYPE gas, U_INT16 sensor_position,
                          U_INT16 *mult, U_INT16 *div, U_INT16 *offset )

/**end_proto**/
{
       /* qualified nl terms are for ss  inlets only */

      if ( (( module == FRNT_INLET_MODULE_NUMBER ) ||
            ( module == BACK_INLET_MODULE_NUMBER ))   &&
           (   type == ( ((U_INT16)INLET_MODULE<<8) | (U_INT16)SS ) ))
      {
          switch ( sensor_position )
          {
              case 1: /* pressure channel  */
                      if ( module == FRNT_INLET_MODULE_NUMBER )
                      {
                           *offset = - Inst_Status.Pneu.Frnt_Inlet.Tcomp_Tables->Pres_Sensor.Parms.Offset
                                     - Inst_Status.Pneu.Frnt_Inlet.Calib.P_Sensor_Offset;
                      }
                      else
                      {
                           *offset = - Inst_Status.Pneu.Back_Inlet.Tcomp_Tables->Pres_Sensor.Parms.Offset
                                     - Inst_Status.Pneu.Back_Inlet.Calib.P_Sensor_Offset;
                      }
                      *mult = 1;
                      *div  = 1;
                      break;

              case 2: /* flow channel      */
                      if ( module == FRNT_INLET_MODULE_NUMBER )
                      {
                           *offset = Inst_Status.Pneu.Frnt_Inlet.Tcomp_Tables->Flow_Sensor.Parms.Offset
                                    +Inst_Status.Pneu.Frnt_Inlet.Calib.F_Sensor_Offset;
                      }
                      else
                      {
                           *offset = Inst_Status.Pneu.Back_Inlet.Tcomp_Tables->Flow_Sensor.Parms.Offset
                                    +Inst_Status.Pneu.Back_Inlet.Calib.F_Sensor_Offset;
                      }
                      switch ( gas )
                      {
                          case N2:  *mult = 1;
                                    *div  = 11;
                                    break;

                          case H2:  *mult = 10;
                                    *div  = 55;
                                    break;

                          case He:  *mult = 10;
                                    *div  = 55;
                                    break;

                          case ArMe:*mult = 1;
                                    *div  = 11;
                                    break;
                      }
                      break;

              case 3: /* alternate channel */
                      if ( module == FRNT_INLET_MODULE_NUMBER )
                      {
                           *offset = Inst_Status.Pneu.Frnt_Inlet.Tcomp_Tables->Flow_Sensor.Parms.Offset
                                    +Inst_Status.Pneu.Frnt_Inlet.Calib.F_Sensor_Offset;
                      }
                      else
                      {
                           *offset = Inst_Status.Pneu.Back_Inlet.Tcomp_Tables->Flow_Sensor.Parms.Offset
                                    +Inst_Status.Pneu.Back_Inlet.Calib.F_Sensor_Offset;
                      }
                      switch ( gas )
                      {
                          case N2:  *mult = 1;
                                    *div  = 11;
                                    break;

                          case H2:  *mult = 10;
                                    *div  = 35;
                                    break;

                          case He:  *mult = 10;
                                    *div  = 35;
                                    break;

                          case ArMe:*mult = 1;
                                    *div  = 11;
                                    break;
                      }
                      break;
          }

      }
      else
      {
           *mult   = 1;
           *div    = 1;
           *offset = 0;
      }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 GetAndSendFactoryInletPids( U_INT16 module , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     U_INT16 address;
     U_INT16 p_term;
     U_INT16 i_term;
     U_INT16 d_term;
     U_INT16 nl_term;
     U_INT16 type;

     U_INT16 mult;
     U_INT16 div;
     U_INT16 offset;

     if ( !ReadModuleType( module, &type ) )
     {
          return FALSE;
     }

     if (( (address = GetFactInletPidEepromAddress( type, gas, sensor_position, I_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &i_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactInletPidEepromAddress( type, gas, sensor_position, P_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &p_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactInletPidEepromAddress( type, gas, sensor_position, D_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &d_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactInletPidEepromAddress( type, gas, sensor_position, NL_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &nl_term ) ))
     {
          return FALSE;
     }

     GetNlGainQualifiers( module, type, gas, sensor_position, &mult, &div, &offset );

     nl_term = nl_term + (U_INT16)( (U_INT32)offset * mult / div );

     return DownloadPids ( channel, p_term, i_term, d_term, nl_term );

}

/**begin_proto**/

BIT8 GetAndSendUserInletPids( U_INT16 module , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     U_INT16 address;
     U_INT16 p_term;
     U_INT16 i_term;
     U_INT16 d_term;
     U_INT16 nl_term;


     if (( (address = GetUserInletPidEepromAddress( gas, sensor_position, I_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &i_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserInletPidEepromAddress( gas, sensor_position, P_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &p_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserInletPidEepromAddress( gas, sensor_position, D_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &d_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserInletPidEepromAddress( gas, sensor_position, NL_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &nl_term ) ))
     {
        return FALSE;
     }


     if (( p_term  != 0 ) &&
         ( i_term  != 0 ) &&
         ( d_term  != 0 ) &&
         ( nl_term != 0 ))
     {
        return DownloadPids ( channel, p_term, i_term, d_term, nl_term );
     }
     else
     {
        return FALSE;
     }

}

/**begin_proto**/

BIT8 GetAndSendFactoryDetPids( U_INT16 module , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     U_INT16 address;
     U_INT16 p_term;
     U_INT16 i_term;
     U_INT16 d_term;
     U_INT16 nl_term;



     if (( (address = GetFactDetPidEepromAddress( gas, sensor_position, I_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &i_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactDetPidEepromAddress( gas, sensor_position, P_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &p_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactDetPidEepromAddress( gas, sensor_position, D_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &d_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactDetPidEepromAddress( gas, sensor_position, NL_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &nl_term ) ))
     {
          return FALSE;
     }

     return DownloadPids ( channel, p_term, i_term, d_term, nl_term );

}

/**begin_proto**/

BIT8 GetAndSendUserDetPids( U_INT16 module , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     U_INT16 address;
     U_INT16 p_term;
     U_INT16 i_term;
     U_INT16 d_term;
     U_INT16 nl_term;


     if (( (address = GetUserDetPidEepromAddress( gas, sensor_position, I_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &i_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserDetPidEepromAddress( gas, sensor_position, P_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &p_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserDetPidEepromAddress( gas, sensor_position, D_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &d_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserDetPidEepromAddress( gas, sensor_position, NL_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &nl_term ) ))
     {
          return FALSE;
     }


     if (( p_term  != 0 ) &&
         ( i_term  != 0 ) &&
         ( d_term  != 0 ) &&
         ( nl_term != 0 ))
     {
        return DownloadPids ( channel, p_term, i_term, d_term, nl_term );
     }
     else
     {
        return FALSE;
     }

}

/**begin_proto**/

BIT8 GetAndSendFactoryAuxPids( U_INT16 module , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     U_INT16 address;
     U_INT16 p_term;
     U_INT16 i_term;
     U_INT16 d_term;
     U_INT16 nl_term;

     if (( (address = GetFactAuxPidEepromAddress( gas, sensor_position, I_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &i_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactAuxPidEepromAddress( gas, sensor_position, P_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &p_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactAuxPidEepromAddress( gas, sensor_position, D_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &d_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetFactAuxPidEepromAddress( gas, sensor_position, NL_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &nl_term ) ))
     {
          return FALSE;
     }

     return DownloadPids ( channel, p_term, i_term, d_term, nl_term );

}

/**begin_proto**/

BIT8 GetAndSendUserAuxPids( U_INT16 module , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     U_INT16 address;
     U_INT16 p_term;
     U_INT16 i_term;
     U_INT16 d_term;
     U_INT16 nl_term;


     if (( (address = GetUserAuxPidEepromAddress( gas, sensor_position, I_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &i_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserAuxPidEepromAddress( gas, sensor_position, P_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &p_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserAuxPidEepromAddress( gas, sensor_position, D_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &d_term ) ))
     {
          return FALSE;
     }

     if (( (address = GetUserAuxPidEepromAddress( gas, sensor_position, NL_TERM_INDEX )) == 0 ) ||
         ( ! ReadEeprom( module, address, &nl_term ) ))
     {
          return FALSE;
     }


     if (( p_term  != 0 ) &&
         ( i_term  != 0 ) &&
         ( d_term  != 0 ) &&
         ( nl_term != 0 ))
     {
        return DownloadPids ( channel, p_term, i_term, d_term, nl_term );
     }
     else
     {
        return FALSE;
     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 GetAndSendInletPids( U_INT16 module , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     BIT8 result;

     result = GetAndSendUserInletPids( module, channel, sensor_position, gas );

     if ( result == FALSE )
     {
         result = GetAndSendFactoryInletPids( module, channel, sensor_position, gas );
     }

     return result;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 GetAndSendDetPids( pDETECTOR_STATUS status , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     BIT8 result;

     if ( status->Config->Type == EPC_OEM )
     {
        return GetAndSendFactoryAuxPids( status->Module_Number, channel, sensor_position, gas );
     } ;

     result = GetAndSendUserDetPids( status->Module_Number, channel, sensor_position, gas );

     if ( result == FALSE )
     {
         result = GetAndSendFactoryDetPids( status->Module_Number, channel, sensor_position, gas );
     }

     return result;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 GetAndSendAuxPids( U_INT16 module , U_INT16 channel, U_INT16 sensor_position, GAS_TYPE gas )

/**end_proto**/
{

     BIT8 result;

     result = GetAndSendUserAuxPids( module, channel, sensor_position, gas );

     if ( result == FALSE )
     {
         result = GetAndSendFactoryAuxPids( module, channel, sensor_position, gas );
     }

     return result;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DownloadInletPids( pINLET_STATUS status )

/**end_proto**/
{

   pINLET_CONFIG config;
   U_INT16 p_channel;
   U_INT16 f_channel;
   U_INT16 alt_channel;
   BIT8    result;

   config = status->Config;

   if ( status->Module_Number == FRNT_INLET_MODULE_NUMBER )
   {
        p_channel = FRNT_INLET_PRESSURE_CHANNEL;
        f_channel = FRNT_INLET_FLOW_CHANNEL;
        alt_channel = FRNT_ALTERNATE_CHANNEL;
   }
   else
   {
        p_channel = BACK_INLET_PRESSURE_CHANNEL;
        f_channel = BACK_INLET_FLOW_CHANNEL;
        alt_channel = BACK_ALTERNATE_CHANNEL;
   }

   result = TRUE;

   if (( status->Config->Type == SS  )     ||  /* G_PTV shows as SS at this pt ... */
       ( status->Config->Type == PP  )     ||
       ( status->Config->Type == ACI )     ||
       ( status->Config->Type == SIMDIST ) ||
       ( status->Config->Type == PTV )     ||
       ( status->Config->Type == CIS3  )   ||
       ( status->Config->Type == CIS4  )   ||
       ( status->Config->Type == COC )     ||
       ( status->Config->Type == VOLATILES ))
   {
        result &= GetAndSendInletPids( status->Module_Number, p_channel, INLET_P_SENSOR, config->Gas_Type );
        result &= GetAndSendInletPids( status->Module_Number, f_channel, INLET_F_SENSOR, config->Gas_Type );
        result &= GetAndSendInletPids( status->Module_Number, alt_channel, INLET_ALTERNATE, config->Gas_Type );
   }
   else if ( status->Config->Type == JIB)
   {
     /* Jill does not have user pid's */
        result &= GetAndSendFactoryInletPids( status->Module_Number, p_channel, INLET_P_SENSOR, config->Gas_Type );
        result &= GetAndSendFactoryInletPids( status->Module_Number, f_channel, INLET_F_SENSOR, config->Gas_Type );
        result &= GetAndSendFactoryInletPids( status->Module_Number, alt_channel, INLET_ALTERNATE, config->Gas_Type );
   }

   if ( ! result )
   {
        if ( status->Position == FRNT_INLET )
        {
            SetException( FI_BAD_PID );
        }
        else
        {
            SetException( BI_BAD_PID );
        }
        config->Functional = FALSE;
   }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DownloadDetPids( pDETECTOR_STATUS status )

/**end_proto**/
{
     pDETECTOR_CONFIG config;
     U_INT16 gas_1;
     U_INT16 gas_2;
     U_INT16 gas_3;
     BIT8    result;

     config = status->Config;

     if ( status->Module_Number == FRNT_DETECTOR_MODULE_NUMBER )
     {
          gas_1 = FRNT_DETECTOR_GAS_1_CHANNEL;
          gas_2 = FRNT_DETECTOR_GAS_2_CHANNEL;
          gas_3 = FRNT_DETECTOR_GAS_3_CHANNEL;
     }
     else
     {
          gas_1 = BACK_DETECTOR_GAS_1_CHANNEL;
          gas_2 = BACK_DETECTOR_GAS_2_CHANNEL;
          gas_3 = BACK_DETECTOR_GAS_3_CHANNEL;
     }

     result = TRUE;

     switch ( config->Type )
     {
         case EPC_OEM:
         case EPC_FPD:
         case EPC_NPD:
         case EPC_FID:  /* do GAS_1, GAS_2, GAS_3 */

             result &= GetAndSendDetPids( status, gas_1, GAS_1_SENSOR, config->Gas_1.Gas_Type );

             /* intentional fall through 'till next break or switch end, whichever is 1st !!  */

         case EPC_TCD:
         case EPC_ECD: /* do        GAS_2, GAS_3 */

             result &= GetAndSendDetPids( status, gas_2, GAS_2_SENSOR, config->Gas_2.Gas_Type );

             /* intentional fall through 'till next break or switch end, whichever is 1st !!  */

         case EPC_LDID:
         case EPC_uECD:
         case EPC_uECD2: /* do               GAS_3 */

             result &= GetAndSendDetPids( status, gas_3, GAS_3_SENSOR, config->Gas_3.Gas_Type );

             break;

         default: ;
     }


     if ( ! result )
     {
         if ( status->Position == FRNT_DET )
         {
             SetException( FD_BAD_PID );
         }
         else
         {
             SetException( BD_BAD_PID );
         }
         status->Config->Functional = FALSE;
     }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DownloadAuxPids( pAUX_STATUS status )

/**end_proto**/
{

     BIT8 result;
     U_INT16 channel;
     U_INT16 sensor;

     result = TRUE;

     switch ( status->Position )
     {

        case AUX_3:
                    channel = AUX_3_CHANNEL;
                    sensor  = GAS_1_SENSOR;
                    break;
        case AUX_4:
                    channel = AUX_4_CHANNEL;
                    sensor  = GAS_2_SENSOR;
                    break;

        case AUX_5:
                    channel = AUX_5_CHANNEL;
                    sensor  = GAS_3_SENSOR;
                    break;

        default:    channel = sensor = 0; /* only to keep lint happy */
     }

     result = GetAndSendAuxPids( status->Module_Number, channel, sensor,  status->Config->Gas_Type );


     if ( ! result )
     {
          SetException( PA_BAD_PID );
          status->Config->Functional = FALSE;
     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DoInlet( pINLET_STATUS status )

/**end_proto**/
{

   pINLET_CONFIG config;
   U_INT16 type;
   U_INT16 version;
   U_INT16 range;

   config = status->Config;
   config->Functional = FALSE;

   if ( (status->Something_There = ModuleExists( status->Module_Number )) == TRUE )
   {
        if  (( ReadModuleType( status->Module_Number, &type ) == FALSE ) || ((MODULE_TYPE)(type>>8) != INLET_MODULE ))
        {
            if ( status->Position == FRNT_INLET )
            {
                SetException( FI_BAD_MODULE );
            }
            else
            {
                SetException( BI_BAD_MODULE );
            }

            config->Type = NO_INLET;
            return;
        }

        if (  ValidModuleCksum( status->Module_Number ) == FALSE  )
        {
            if ( status->Position == FRNT_INLET )
            {
                SetException( FI_BAD_CKSUM );
            }
            else
            {
                SetException( BI_BAD_CKSUM );
            }

            config->Type = NO_INLET;
            return;
        }

        config->Type = (INLET_TYPE) (type & 0x00ff);

        if (( ReadModuleVersion( status->Module_Number, &version ) == FALSE ) || ( version != REQUIRED_INLET_VERSION ))
        {

            /* revisit */
            if ( version == 0x0105 )
            {
                (void)ReadEeprom( status->Module_Number, PS_RANGE, &range );
                (void)InitInletEEPROM ( status->Module_Number, (U_INT16)config->Type, range, 0,0,0,0 );
                DoInlet( status );
            }
            else if ( version == 0x0106 )
            {
                UpdateInletEeprom0107( status );
                (void)ReadEeprom( status->Module_Number, PS_RANGE, &range );
                (void)InitInletEEPROM ( status->Module_Number, (U_INT16)config->Type, range, 0,0,0,0 );
                DoInlet( status );
            }
            else if ( version == 0x0108 )
            {
                UpdateInletEeprom0109( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0109 )
            {
                UpdateInletEeprom010A( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x010A )
            {
                UpdateInletEeprom010B( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x010B )
            {
                UpdateInletEeprom010C( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x010C )
            {
                UpdateInletEeprom010D( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x010D )
            {
                UpdateInletEeprom010E( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x010E )
            {
                UpdateInletEeprom010F( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x010F )
            {
                UpdateInletEeprom0110( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0110 )
            {
                UpdateInletEeprom0111( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0111 )
            {
                UpdateInletEeprom0112( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0112 )
            {
                UpdateInletEeprom0113( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0113 )
            {
                UpdateInletEeprom0114( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0114 )
            {
                UpdateInletEeprom0115( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0115 )
            {
                UpdateInletEeprom0116( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0116 )
            {
                UpdateInletEeprom0117( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0117 )
            {
                UpdateInletEeprom0118( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0118 )
            {
                UpdateInletEeprom0200( status );
                DoInlet( status );
                return;
            }
            else if ( version == 0x0200 )
            {
                UpdateInletEeprom0201( status );
                DoInlet( status );
                return;
            }
            else
            {
                if ( status->Position == FRNT_INLET )
                {
                    SetException( FI_BAD_EEPROM_REV );
                }
                else
                {
                    SetException( BI_BAD_EEPROM_REV );
                }
                config->Type = NO_INLET;
            }
            return;
        }

        switch ( config->Type )
        {
             case PTV:
             case COC:
             case JIB:
             case ACI:
             case SIMDIST:
             case G_PTV:    /* NOT mapped to SS at this pt */
             case CIS3:
#ifdef CIS4_SUPPORT
             case CIS4:
#endif
             case VOLATILES:
             case PP:
             case SS:  ReadFlowScaling( status->Module_Number, GAS_2_SENSOR, &status->IU_Scaling );
                       DoAPSensor( status->Module_Number,
                                   GAS_1_SENSOR,
                                   &status->P_Sensor_Range,
                                   &status->Dcm2_Per_IU,
                                   &config->P_Sensor_Range );
                       status->Real_PS_Range = CalcRealMaxPres( status->P_Sensor_Range, status->Dcm2_Per_IU );
                       config->Functional = TRUE;

                       break;

#ifndef CIS4_SUPPORT
             case CIS4:
#endif
             default:  if ( status->Position == FRNT_INLET )
                       {
                           SetException( FI_UNSUPPORTED_TYPE );
                       }
                       else
                       {
                           SetException( BI_UNSUPPORTED_TYPE );
                       }
                       config->Type = NO_INLET;
                       break;
        }
   }
   else
   {   /* not an epc inlet, manual inlet -- maybe */

       if ( PF_Reset == TRUE )
       {
           /* default the inlet types to unknown */
           /*   Zones will have a function */
           /* that runs after initialize pneumatics that will */
           /* check for a heater-sensor pair to recognise     */
           /* and set NO_INLET if heater-sensor is missing    */

           config->Type = UNKNOWN_INLET;
           config->Gas_Type = He;
           config->P_Sensor_Range = INVALID_PS_RANGE;
           status->P_Sensor_Range = INVALID_PS_RANGE;
           status->Real_PS_Range  = INVALID_PS_RANGE;
           status->Dcm2_Per_IU    = INVALID_PS_SCALE;
           status->IU_Scaling     = INVALID_FS_SCALE;
           config->Functional = TRUE;
       }
       else
       {
           if (( config->Type == PP )       ||
               ( config->Type == SS )       ||
               ( config->Type == JIB)       ||
               ( config->Type == ACI)       ||
               ( config->Type == SIMDIST)   ||
               ( config->Type == PTV)       ||
               ( config->Type == G_PTV)     ||
               ( config->Type == CIS3 )     ||
               ( config->Type == CIS4 )     ||
               ( config->Type == VOLATILES) ||
               ( config->Type == COC ))
           {
               /* if we are booting warm, and a previously epc inlet */
               /* has disappeared, reset it down to unknown.         */
               config->Type = UNKNOWN_INLET;
           }
       }
   }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DoDetector( pDETECTOR_STATUS status )

/**end_proto**/
{
   pDETECTOR_CONFIG config;
   U_INT16 type;
   U_INT16 version;

   config = status->Config;
   config->Type = (EEPROM_DET_TYPE)NO_DET;
   config->Functional = FALSE;

   if ( (status->Something_There = ModuleExists( status->Module_Number )) == TRUE )
   {

        if (
            ( ReadModuleType( status->Module_Number, &type ) == FALSE ) ||
            ( ((MODULE_TYPE)(type>>8) != DET_MODULE ) && ((MODULE_TYPE)(type>>8) != AUX_MODULE ) )
           )
        {
            if ( status->Position == FRNT_DET )
            {
                SetException( FD_BAD_MODULE );
            }
            else
            {
                SetException( BD_BAD_MODULE );
            }
            return;
        }

        if ( ValidModuleCksum( status->Module_Number ) == FALSE )
        {
            if ( status->Position == FRNT_DET )
            {
                SetException( FD_BAD_CKSUM );
            }
            else
            {
                SetException( BD_BAD_CKSUM );
            }
            return;
        }

        if ( type == (U_INT16)AUX_MODULE << 8 )
        {
            config->Type = EPC_OEM ;
            if (( ReadModuleVersion( status->Module_Number, &version ) == FALSE ) || ( version != REQUIRED_AUX_VERSION ))
            {
                if ( UpdateAuxProm( status->Module_Number, version ) == (U_INT16)AUX_MODULE )
                {
                    DoDetector( status );
                }
                return;
            }

        }
        else
        {
            config->Type = (EEPROM_DET_TYPE)(type & 0x00ff);


            if (( ReadModuleVersion( status->Module_Number, &version ) == FALSE ) || ( version != REQUIRED_DET_VERSION ))
            {

                if ( version == 0x0105 )
                {
                    (void)WriteEeprom( status->Module_Number, 0x1e, 0xc000 );  /* fix up span */
                    (void)WriteEeprom( status->Module_Number, 0x1f, 0xc000 );  /* fix up span */
                    (void)WriteEeprom( status->Module_Number, 0x20, 0xc000 );  /* fix up span */
                    (void)WriteEeprom( status->Module_Number, VERSION, 0x0106 );  /* fix up span */
                    DoDetector( status );
                }
                else if ( version == 0x0106 )
                {
                    UpdateDetectorEeprom0107( status );
                    DoDetector( status );
                }
                else if ( version == 0x0108 )
                {
                    UpdateDetEeprom109( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x0109 )
                {
                    UpdateDetEeprom10A( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x010A )
                {
                    UpdateDetEeprom10B( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x010B )
                {
                    UpdateDetEeprom10C( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x010C )
                {
                    UpdateDetEeprom10D( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x010D )
                {
                    UpdateDetEeprom10E( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x010E )
                {
                    UpdateDetEeprom10F( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x010F )
                {
                    UpdateDetEeprom110( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x0110 )
                {
                    UpdateDetEeprom111( status );
                    DoDetector( status );
                    return;
                }
                else if ( version == 0x0111 )
                {
                    UpdateDetEeprom200( status );
                    DoDetector( status );
                    return;
                }
                else
                {
                     if ( status->Position == FRNT_DET )
                     {
                         SetException( FD_BAD_EEPROM_REV );
                     }
                     else
                     {
                         SetException( BD_BAD_EEPROM_REV );
                     }

                     return;
                }
            }
        }

        switch ( config->Type )
        {
             case EPC_OEM:
             case EPC_FPD:
             case EPC_NPD:
             case EPC_FID: ReadFlowScaling( status->Module_Number, GAS_1_SENSOR, &status->Gas_1.IU_Scaling );

                           DoAPSensor( status->Module_Number,
                                       GAS_1_SENSOR,
                                       &status->Gas_1.P_Sensor_Range,
                                       &status->Gas_1.Dcm2_Per_IU,
                                       &config->Gas_1.P_Sensor_Range );

                           /* intentional fall through 'till next break or switch end, whichever is 1st !!  */

             case EPC_TCD:
             case EPC_ECD: ReadFlowScaling( status->Module_Number, GAS_2_SENSOR, &status->Gas_2.IU_Scaling );

                           DoAPSensor( status->Module_Number,
                                       GAS_2_SENSOR,
                                       &status->Gas_2.P_Sensor_Range,
                                       &status->Gas_2.Dcm2_Per_IU,
                                       &config->Gas_2.P_Sensor_Range );

                           config->Gas_2.P_Sensor_Range = status->Gas_2.P_Sensor_Range * status->Gas_2.Dcm2_Per_IU;

                           /* intentional fall through 'till next break or switch end, whichever is 1st !!  */

             case EPC_LDID:
             case EPC_uECD:
             case EPC_uECD2:
                           ReadFlowScaling( status->Module_Number, GAS_3_SENSOR, &status->Gas_3.IU_Scaling );

                                /* use makeup flow scaling for combinded flow calculations */
                           ReadFlowScaling( status->Module_Number, GAS_3_SENSOR, &status->IU_Scaling );

                           DoAPSensor( status->Module_Number,
                                       GAS_3_SENSOR,
                                       &status->Gas_3.P_Sensor_Range,
                                       &status->Gas_3.Dcm2_Per_IU,
                                       &config->Gas_3.P_Sensor_Range );

                           config->Gas_3.P_Sensor_Range = status->Gas_3.P_Sensor_Range * status->Gas_3.Dcm2_Per_IU;
                           config->Functional = TRUE;
                           break; /* and we are OUT'A HERE !!! */

             case MAN_FID:
             case MAN_TCD:
             case MAN_FPD:
             case MAN_ECD:
             case MAN_NPD: config->Gas_1.P_Sensor_Range = INVALID_PS_RANGE;
                           config->Gas_2.P_Sensor_Range = INVALID_PS_RANGE;
                           config->Gas_3.P_Sensor_Range = INVALID_PS_RANGE;

                           status->Gas_1.P_Sensor_Range = INVALID_PS_RANGE;
                           status->Gas_2.P_Sensor_Range = INVALID_PS_RANGE;
                           status->Gas_3.P_Sensor_Range = INVALID_PS_RANGE;

                           status->Gas_1.Dcm2_Per_IU = INVALID_PS_SCALE;
                           status->Gas_2.Dcm2_Per_IU = INVALID_PS_SCALE;
                           status->Gas_3.Dcm2_Per_IU = INVALID_PS_SCALE;

                           status->Gas_1.IU_Scaling = INVALID_FS_SCALE;
                           status->Gas_2.IU_Scaling = INVALID_FS_SCALE;
                           status->Gas_3.IU_Scaling = INVALID_FS_SCALE;
                           config->Functional = TRUE;
                           break;

             default:      if ( status->Position == FRNT_DET )
                           {
                               SetException( FD_UNSUPPORTED_TYPE );
                           }
                           else
                           {
                               SetException( BD_UNSUPPORTED_TYPE );
                           }

        }
   }
   else
   {
       config->Type = (EEPROM_DET_TYPE)NO_DET;
       config->Gas_1.P_Sensor_Range = INVALID_PS_RANGE;
       config->Gas_2.P_Sensor_Range = INVALID_PS_RANGE;
       config->Gas_3.P_Sensor_Range = INVALID_PS_RANGE;

       status->Gas_1.P_Sensor_Range = INVALID_PS_RANGE;
       status->Gas_2.P_Sensor_Range = INVALID_PS_RANGE;
       status->Gas_3.P_Sensor_Range = INVALID_PS_RANGE;

       status->Gas_1.Dcm2_Per_IU = INVALID_PS_SCALE;
       status->Gas_2.Dcm2_Per_IU = INVALID_PS_SCALE;
       status->Gas_3.Dcm2_Per_IU = INVALID_PS_SCALE;

       status->Gas_1.IU_Scaling = INVALID_FS_SCALE;
       status->Gas_2.IU_Scaling = INVALID_FS_SCALE;
       status->Gas_3.IU_Scaling = INVALID_FS_SCALE;
       config->Functional = TRUE;
   }

}

/**begin_proto**/

void DoNonEpcDet( pDETECTOR_STATUS status )

/**end_proto**/
{
   pDETECTOR_CONFIG config;
   U_INT16 type;

   config = status->Config;
   config->Type = (EEPROM_DET_TYPE)NO_DET;
   config->Functional = FALSE;

   if ( (status->Something_There = ModuleExists( status->Module_Number )) == TRUE)
   {
        /* revisit: do we want to bother checking a chksum here? the only valid word is the module type. */

        if (( ReadModuleType( status->Module_Number, &type ) == FALSE ) || ((MODULE_TYPE)(type>>8) != DET_MODULE ))
        {
            if ( status->Position == FRNT_DET )
            {
                SetException( FD_BAD_MODULE );
            }
            else
            {
                SetException( BD_BAD_MODULE );
            }
            return;
        }
        config->Type = (EEPROM_DET_TYPE) (type & 0x00ff);

        switch ( config->Type )
        {
             case MAN_FID:
             case MAN_TCD:
             case MAN_FPD:
             case MAN_ECD:
             case MAN_NPD: config->Functional = TRUE;
                           break;

             default:      if ( status->Position == FRNT_DET )
                           {
                               SetException( FD_UNSUPPORTED_TYPE );
                           }
                           else
                           {
                               SetException( BD_UNSUPPORTED_TYPE );
                           }
        }
   }

   config->Gas_1.P_Sensor_Range = INVALID_PS_RANGE;
   config->Gas_2.P_Sensor_Range = INVALID_PS_RANGE;
   config->Gas_3.P_Sensor_Range = INVALID_PS_RANGE;

   status->Gas_1.P_Sensor_Range = INVALID_PS_RANGE;
   status->Gas_2.P_Sensor_Range = INVALID_PS_RANGE;
   status->Gas_3.P_Sensor_Range = INVALID_PS_RANGE;

   status->Gas_1.Dcm2_Per_IU = INVALID_PS_SCALE;
   status->Gas_2.Dcm2_Per_IU = INVALID_PS_SCALE;
   status->Gas_3.Dcm2_Per_IU = INVALID_PS_SCALE;

   status->Gas_1.IU_Scaling = INVALID_FS_SCALE;
   status->Gas_2.IU_Scaling = INVALID_FS_SCALE;
   status->Gas_3.IU_Scaling = INVALID_FS_SCALE;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

U_INT16  UpdateAuxProm( U_INT8 modul , U_INT16 versn)
{
     switch ( versn )
     {
            case 0x0108 :
                 UpdateAuxEeprom109( modul  );
                 return (U_INT16)AUX_MODULE;

            case 0x0109 :
                 UpdateAuxEeprom10A( modul  );
                 return (U_INT16)AUX_MODULE;

            case 0x010A :
                 UpdateAuxEeprom10B( modul  );
                 return (U_INT16)AUX_MODULE;

            case 0x010B :
                 UpdateAuxEeprom10C( modul  );
                 return (U_INT16)AUX_MODULE;

            case 0x010C :
                 UpdateAuxEeprom10D( modul  );
                 return (U_INT16)AUX_MODULE;

            case 0x010D :
                 UpdateAuxEeprom10E( modul  );
                 return (U_INT16)AUX_MODULE;

            case 0x010E :
                 UpdateAuxEeprom200( modul  );
                 return (U_INT16)AUX_MODULE;

            default:
                 SetException( AX_BAD_EEPROM_REV );
                 return (U_INT16)NO_AUX;

        }
}

/**begin_proto**/

void DoPneuAux( pAUXILIARY_STATUS status )

/**end_proto**/
{

   U_INT16 type;
   U_INT16 version;

   Inst_Config.Pneu.Aux_3.Functional = FALSE;
   Inst_Config.Pneu.Aux_4.Functional = FALSE;
   Inst_Config.Pneu.Aux_5.Functional = FALSE;

   if ( ( status->Something_There = ModuleExists( status->Module_Number ) ) == TRUE )
   {
        if  (( ReadModuleType( status->Module_Number, &type ) == FALSE ) || ( (MODULE_TYPE)(type>>8) != AUX_MODULE ))
        {
            SetException( AX_BAD_MODULE );
            /* type = (U_INT16)NO_AUX; */

            return;
        }

        if ( ValidModuleCksum( status->Module_Number ) == FALSE )
        {
            SetException( PA_BAD_CKSUM );
            /* type = (U_INT16)NO_AUX; */

            return;
        }


        if (( ReadModuleVersion( status->Module_Number, &version ) == FALSE ) || ( version != REQUIRED_AUX_VERSION ))
        {
            if ( UpdateAuxProm( status->Module_Number, version ) == (U_INT16)AUX_MODULE )
            {
                 DoPneuAux( status );
            }
            return;
        }

        Inst_Config.Pneu.Aux_Present = TRUE;

        DoAPSensor( status->Module_Number,
                    GAS_1_SENSOR,
                    &status->Aux_3.P_Sensor_Range,
                    &status->Aux_3.Dcm2_Per_IU,
                    &status->Aux_3.Config->P_Sensor_Range );
        status->Aux_3.Real_PS_Range = CalcRealMaxPres( status->Aux_3.P_Sensor_Range, status->Aux_3.Dcm2_Per_IU );

        DoAPSensor( status->Module_Number,
                    GAS_2_SENSOR,
                    &status->Aux_4.P_Sensor_Range,
                    &status->Aux_4.Dcm2_Per_IU,
                    &status->Aux_4.Config->P_Sensor_Range );
        status->Aux_4.Real_PS_Range = CalcRealMaxPres( status->Aux_4.P_Sensor_Range, status->Aux_4.Dcm2_Per_IU );

        DoAPSensor( status->Module_Number,
                    GAS_3_SENSOR,
                    &status->Aux_5.P_Sensor_Range,
                    &status->Aux_5.Dcm2_Per_IU,
                    &status->Aux_5.Config->P_Sensor_Range );
        status->Aux_5.Real_PS_Range = CalcRealMaxPres( status->Aux_5.P_Sensor_Range, status->Aux_5.Dcm2_Per_IU );

       Inst_Config.Pneu.Aux_3.Functional = TRUE;
       Inst_Config.Pneu.Aux_4.Functional = TRUE;
       Inst_Config.Pneu.Aux_5.Functional = TRUE;
   }
   else
   {
        Inst_Config.Pneu.Aux_Present = FALSE;
        status->Aux_3.Config->P_Sensor_Range = INVALID_PS_RANGE;
        status->Aux_4.Config->P_Sensor_Range = INVALID_PS_RANGE;
        status->Aux_5.Config->P_Sensor_Range = INVALID_PS_RANGE;

        status->Aux_3.Real_PS_Range = INVALID_PS_RANGE;
        status->Aux_4.Real_PS_Range = INVALID_PS_RANGE;
        status->Aux_5.Real_PS_Range = INVALID_PS_RANGE;

        status->Aux_3.P_Sensor_Range = INVALID_PS_RANGE;
        status->Aux_4.P_Sensor_Range = INVALID_PS_RANGE;
        status->Aux_5.P_Sensor_Range = INVALID_PS_RANGE;
   }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ValidateInletConfig ( pINLET_STATUS status )

/**end_proto**/

{
     pINLET_CONFIG config;

     config = status->Config;

     if ( (( config->Type == PP      )   ||
           ( config->Type == COC     )   ||
           ( config->Type == SS      )   ||
           ( config->Type == PTV     )   ||
           ( config->Type == ACI     )   ||
           ( config->Type == SIMDIST )   ||
           ( config->Type == CIS3    )   ||
           ( config->Type == CIS4    )   ||
           ( config->Type == VOLATILES ) ||
           ( config->Type == G_PTV ) )   &&

         (( status->P_Sensor_Range == INVALID_PS_RANGE ) ||
          ( status->Dcm2_Per_IU    == INVALID_PS_SCALE ) ||
          ( status->IU_Scaling     == INVALID_FS_SCALE )) )
     {
         config->Functional = FALSE;
         if ( status->Position == FRNT_INLET )
         {
             SetException ( FI_BAD_CONSTS );
         }
         else
         {
             SetException ( BI_BAD_CONSTS );
         }
     }

#ifdef SUPPORT_UNSUPPORTED_INLET_TYPES

     if ( config->Type == G_PTV )
     {
        config->Type      = SS;
        config->True_Type = G_PTV;
     }
     else if ( config->Type == ACI )
     {
        config->Type      = COC;
        config->True_Type = ACI;
     }
     else if (( config->Type == MANUAL_ACI) ||
              ((config->Type == MANUAL_COC) && (config->True_Type==MANUAL_ACI)))
     {
        config->Type      = MANUAL_COC;
        config->True_Type = MANUAL_ACI;
     }
     else
     {
        config->True_Type = config->Type;
     }
#endif


     if ( config->True_Type != (INLET_TYPE)GetZoneType( (status->Position == FRNT_INLET) ?
                                                                  pFRONT_INLET_TEMP :
                                                                  pBACK_INLET_TEMP ) )
     {
         DetermineInletZoneConfig( config->True_Type, (status->Position == FRNT_INLET) ? pFRONT_INLET_TEMP : pBACK_INLET_TEMP ) ;
     }


     if (( config->Type == MANUAL_PP       ) ||
         ( config->Type == MANUAL_ACI      ) ||
         ( config->Type == MANUAL_COC      ) ||
         ( config->Type == MANUAL_SS       ) ||
         ( config->Type == NO_INLET        ) ||
         ( config->Type == UNKNOWN_INLET ))
     {
       /* we have a manual inlet! */
         status->Config->Functional = TRUE;
         /* now set up values for the flow calculator */
         status->P_Sensor_Range = 0xa854;
         status->Dcm2_Per_IU    = 0x00a0;
         status->IU_Scaling     = 0x4000;

     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ValidateColumnConfig ( pCOLUMN_STATUS status )

/**end_proto**/

{
  (void)status;
#if 0
    pCOLUMN_CONFIG config;
    pCOLUMN_CONFIG wkfile;



    config = status->Config;
    wkfile = status->Wkfile_Config;


     if (( config->Length != wkfile->Length ) ||
         ( config->Diam   != wkfile->Diam   ) ||
         ( config->Film_Thickness   != wkfile->Film_Thickness   ) ||
         ( config->Source != wkfile->Source ) ||
         ( config->Outlet != wkfile->Outlet ))
     {

          LoadDefaultColumnSetpts( status );

          if ( PF_Reset == FALSE )
          {
               if ( status->Position == 1 )
               {
                   SetException ( C1_CONFIG_CHANGED );
               }
               else
               {
                   SetException ( C2_CONFIG_CHANGED );
               }
          }
     }
#endif

}


/**begin_proto**/

BIT8 OddCombos( EEPROM_DET_TYPE pneu_id , DET_TYPE card_id )

/**end_proto**/
{
     switch ( card_id  )
     {
        case uECD    :  return pneu_id == EPC_uECD2 ;
                             /* allow " signal_pca=uecd AND pneu_manifold=uMachined_uecd " as a special case */
                             /* This facilitates uMachined uECD developement that MAY happen in future.      */

        case OEM_FID  : return pneu_id == EPC_OEM ; /*    EPC_OEM = (int)OEM_AIB | EPC_DET_BIT   */
                                                    /*    "typedefs.h" line 201 of 482 --41%--   */

     }

     return FALSE ;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ValidateDetectorConfig ( pDETECTOR_STATUS status )

/**end_proto**/
{
      pDETECTOR_CONFIG config;

      config = status->Config;

     switch ( config->Type )
     {
        case EPC_OEM:
        case EPC_FID:
        case EPC_NPD:
        case EPC_FPD: if (( IamAdirtball() ) ||
                          ( status->Gas_1.Dcm2_Per_IU    == INVALID_PS_SCALE ) ||
                          ( status->Gas_2.Dcm2_Per_IU    == INVALID_PS_SCALE ) ||
                          ( status->Gas_3.Dcm2_Per_IU    == INVALID_PS_SCALE ) ||
                          ( status->Gas_1.IU_Scaling     == INVALID_FS_SCALE ) ||
                          ( status->Gas_2.IU_Scaling     == INVALID_FS_SCALE ) ||
                          ( status->Gas_3.IU_Scaling     == INVALID_FS_SCALE ))
                      {
                          config->Functional = FALSE;
                          if ( status->Position == FRNT_DET )
                          {
                              SetException ( FD_BAD_CONSTS );
                          }
                          else
                          {
                              SetException ( BD_BAD_CONSTS );
                          }
                      }
                      break;

        case EPC_ECD:
        case EPC_TCD: if (( IamAdirtball() ) ||
                          ( status->Gas_2.Dcm2_Per_IU    == INVALID_PS_SCALE ) ||
                          ( status->Gas_3.Dcm2_Per_IU    == INVALID_PS_SCALE ) ||
                          ( status->Gas_2.IU_Scaling     == INVALID_FS_SCALE ) ||
                          ( status->Gas_3.IU_Scaling     == INVALID_FS_SCALE ))
                      {
                          config->Functional = FALSE;
                          if ( status->Position == FRNT_DET  )
                          {
                              SetException ( FD_BAD_CONSTS );
                          }
                          else
                          {
                              SetException ( BD_BAD_CONSTS );
                          }
                      }
                      break;

        case EPC_LDID:
        case  EPC_uECD:
        case EPC_uECD2: if (( IamAdirtball() ) ||
                          ( status->Gas_3.Dcm2_Per_IU    == INVALID_PS_SCALE ) ||
                          ( status->Gas_3.IU_Scaling     == INVALID_FS_SCALE ))
                      {
                          config->Functional = FALSE;
                          if ( status->Position == FRNT_DET  )
                          {
                              SetException ( FD_BAD_CONSTS );
                          }
                          else
                          {
                              SetException ( BD_BAD_CONSTS );
                          }
                      }
                      break;
     }

     /* any electronics board works with cpf */
     if ( GetCPFDetPneuPresence( (POSITION)status->Position ) )  return;


     if ( status->Position == FRNT_DET )
     {
          if ( (DET_TYPE)(DISCRETE_IN1 & 0x0f) == AIB )
          {
               config->Functional = FALSE;
          }
     }
     else
     {
          if ( (DET_TYPE)(( DISCRETE_IN1 & 0xf0)>>4) == AIB )
          {
               config->Functional = FALSE;
          }
     }

     /* no pneumatics needed for electrometer only case */
     if ( ManualElectrometer( (POSITION)status->Position ) )  return;

     if ( status->Config->Type != (EEPROM_DET_TYPE)NO_DET )
     {
          /* proper electronics? */

          if ( status->Position == FRNT_DET )
          {
               if ( OddCombos( config->Type, (DET_TYPE)(DISCRETE_IN1&0x0f) ) ) return ;

               if ( ( (U_INT16)config->Type & 0xf ) != (DISCRETE_IN1 & 0x0f) )
               {
                   config->Functional = FALSE;
                   SetException ( FD_PNEU_ELEC_MISMATCH );
               }
          }
          else
          {
               if ( OddCombos( config->Type, (DET_TYPE)((DISCRETE_IN1&0xf0)>>4) ) ) return ;

               if ( ( (U_INT16)config->Type & 0xf ) != ( ( DISCRETE_IN1 & 0xf0)>>4) )
               {
                   config->Functional = FALSE;
                   SetException ( BD_PNEU_ELEC_MISMATCH );
               }
          }
     }
     else
     {
         config->Functional = FALSE;
     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ValidateAuxConfig ( pAUX_STATUS status )

/**end_proto**/
{
    pAUX_CONFIG config;

    config = status->Config;

    if ( !Inst_Config.Pneu.Aux_Present )
    {
         config->Functional = FALSE;
         return;
    }

    if ( status->P_Sensor_Range == INVALID_PS_RANGE )
    {
         config->Functional = FALSE;

         switch ( status->Position )
         {
            case AUX_3: SetException( AUX_3_BROKEN ); break;
            case AUX_4: SetException( AUX_4_BROKEN ); break;
            case AUX_5: SetException( AUX_5_BROKEN ); break;
         }
    }
    else
    {
         config->Functional = TRUE;
    }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ValidatePneuConfig(void)

/**end_proto**/
{

      ValidateInletConfig ( &Inst_Status.Pneu.Frnt_Inlet );
      ValidateInletConfig ( &Inst_Status.Pneu.Back_Inlet );

      ValidateDetectorConfig ( &Inst_Status.Pneu.Frnt_Detector );
      ValidateDetectorConfig ( &Inst_Status.Pneu.Back_Detector );

      ValidateAuxConfig ( &Inst_Status.Pneu.Aux.Aux_3 );
      ValidateAuxConfig ( &Inst_Status.Pneu.Aux.Aux_4 );
      ValidateAuxConfig ( &Inst_Status.Pneu.Aux.Aux_5 );

      ValidateColumnConfig( &Inst_Status.Pneu.Column_1 );
      ValidateColumnConfig( &Inst_Status.Pneu.Column_2 );

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void InitializePneumatics(void)

/**end_proto**/
{

     InitResource ( &Inst_Status.Pneu.Resource_Lock );
     LockResource ( &Inst_Status.Pneu.Resource_Lock );

     InitPneuStores();

     if ( PF_Reset == TRUE )
     {
           /* default the inlet types to unknown */
           /* if epc, readpcbconfig will update to */
           /* epc inlet types.  Zones, will have a function */
           /* that runs after initialize pneumatics that will */
           /* check for a heater-sensor pair to recognise     */
           /* and configure manual inlets */

           Inst_Config.Pneu.Frnt_Inlet.Type = UNKNOWN_INLET;
           DetermineInletZoneConfig( UNKNOWN_INLET, pFRONT_INLET_TEMP ) ;

           Inst_Config.Pneu.Back_Inlet.Type = UNKNOWN_INLET;
           DetermineInletZoneConfig( UNKNOWN_INLET, pBACK_INLET_TEMP ) ;
     }

     ReleaseResource( &Inst_Status.Pneu.Resource_Lock );
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DoInletTComp( pINLET_STATUS status )

/**end_proto**/
{

    switch ( status->Config->Type )
    {
         case JIB:
         case SS:                                     /* G_PTV shows as SS at this pt ... */
         case PTV:
         case CIS3 :
         case CIS4:
         case ACI:
         case SIMDIST:
         case VOLATILES:
         case PP:  InitFlowTempCompTable ( status );
                   InitPresTempComp      ( status );
                   InitPurgeRegComp      ( status );
                   break;

         case COC: InitPresTempComp      ( status );
                   break;

    }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DeterminePneuConfig( void )

/**end_proto**/
{

     TestPneuKeyShortcut();

     if ( Stepping )
     {
         InitPneuKeys();
         PneuFakeDisplay();
     }

     /* make sure the Solenoid valve drive for manual  */
     /* detectors is off!.  512 will send the mask out */
     /* as soon as it is alive.                        */

     InitSolenoidValveDrive();


     if ((ZONES_CONFIG2 & PNEU_BD_PRESENT) == 0)
     { /* pcb is really there */

        if ( Inst_Status.Pneu.Pneu_Dsp_Alive == FALSE ) return ;

        Inst_Config.Pneu.Dirt_Ball = FALSE;
printf("DoInlet Frnt\n");
        DoInlet( &Inst_Status.Pneu.Frnt_Inlet );
printf("DoInlet Back\n");
        DoInlet( &Inst_Status.Pneu.Back_Inlet );

printf("DoDetector Frnt\n");
        DoDetector( &Inst_Status.Pneu.Frnt_Detector );
printf("DoDetector Back\n");
        DoDetector( &Inst_Status.Pneu.Back_Detector );

printf("DoPneuAux Aux\n");
        DoPneuAux( &Inst_Status.Pneu.Aux );

        ValidatePneuConfig();
     }
     else
     {
         Inst_Config.Pneu.Dirt_Ball = TRUE;

         Inst_Config.Pneu.Frnt_Inlet.Functional = TRUE;
         Inst_Config.Pneu.Back_Inlet.Functional = TRUE;

         if ( !GetSensorPresence (pFRONT_INLET_TEMP) )
         {
             Inst_Config.Pneu.Frnt_Inlet.Type = NO_INLET;
             Inst_Config.Pneu.Frnt_Inlet.True_Type = NO_INLET;
             DetermineInletZoneConfig( NO_INLET, pFRONT_INLET_TEMP ) ;
         }
         else if ( PF_Reset == TRUE )
         {
             Inst_Config.Pneu.Frnt_Inlet.Type = UNKNOWN_INLET;
             Inst_Config.Pneu.Frnt_Inlet.True_Type = UNKNOWN_INLET;
             DetermineInletZoneConfig( UNKNOWN_INLET, pFRONT_INLET_TEMP ) ;
         }



         if ( !GetSensorPresence (pBACK_INLET_TEMP) )
         {
             Inst_Config.Pneu.Back_Inlet.Type = NO_INLET;
             Inst_Config.Pneu.Back_Inlet.True_Type = NO_INLET;
             DetermineInletZoneConfig( NO_INLET, pBACK_INLET_TEMP ) ;
         }
         else if ( PF_Reset == TRUE )
         {
             Inst_Config.Pneu.Back_Inlet.Type = UNKNOWN_INLET;
             Inst_Config.Pneu.Back_Inlet.True_Type = UNKNOWN_INLET;
             DetermineInletZoneConfig( UNKNOWN_INLET, pBACK_INLET_TEMP ) ;
         }

         DoNonEpcDet( &Inst_Status.Pneu.Frnt_Detector );
         DoNonEpcDet( &Inst_Status.Pneu.Back_Detector );

         ValidateDetectorConfig ( &Inst_Status.Pneu.Frnt_Detector );
         ValidateDetectorConfig ( &Inst_Status.Pneu.Back_Detector );
     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void SetupPneuAuxRamp( pAUX_STATUS status )

/**end_proto**/
{

        SetRampSetptPointer( (pRAMPINFO)status->Ramp_Info, (INT32 *)&status->Ramp_Setpt.Ramp_Pressure );

        if (( !status->Config->Functional ) || ( status->Controlled_By_Column ) || (status->Wkfile->On_Off == OFF ))
        {
            DisableRamp(  (pRAMPINFO)status->Ramp_Info );
        }
        else
        {
            EnableRamp(  (pRAMPINFO)status->Ramp_Info );
        }


}


/**begin_proto**/

void SetupPneuColRamp( pCOLUMN_STATUS status )

/**end_proto**/
{

       if ( GetColumnRampType ( status )  == FLOW_RAMP )
       {
            SetRampSetptPointer( (pRAMPINFO)status->Ramp_Info, (INT32 *)&status->Ramp_Setpt.Column_V_Flow );
            EnableRamp(  (pRAMPINFO)status->Ramp_Info );
       }
       else if ( GetColumnRampType ( status )  == PRESSURE_RAMP )
       {
            SetRampSetptPointer( (pRAMPINFO)status->Ramp_Info, (INT32 *)&status->Ramp_Setpt.Head_Pressure );
            EnableRamp(  (pRAMPINFO)status->Ramp_Info );
       }


}



/**begin_proto**/

void SetupPneuRamps(void)

/**end_proto**/
{

        SetupPneuColRamp( &Inst_Status.Pneu.Column_1 );
        SetupPneuColRamp( &Inst_Status.Pneu.Column_2 );
        SetupPneuAuxRamp( &Inst_Status.Pneu.Aux.Aux_3 );
        SetupPneuAuxRamp( &Inst_Status.Pneu.Aux.Aux_4 );
        SetupPneuAuxRamp( &Inst_Status.Pneu.Aux.Aux_5 );

        UpdatePneuRampInitValues();
}

/**begin_proto**/

void GetOEMDetFritFlags ( void )

/**end_proto**/
{
   U_INT16 *intptr;
   U_INT16 result;
   U_INT16 maxflow ;
   BIT8    chnl;
   POSITION pos;
   GAS_TYPE type;

   intptr = &result ;

   for ( pos=FRONT; pos <= BACK; pos++  )
   {
      for( chnl=0; chnl < 3; chnl++   )
      {
         ReadSensorRange(2+(U_INT8)pos,chnl+1,intptr);
         if ((result != INVALID_PS_RANGE) && (1 != *GetDetGasLabel(pos,chnl+1)))
         {
            OEMDetFritFlags[pos][chnl] = 0 ;
            for (type = N2; type < UNKNOWN_GAS; type++ )
            {
               result =  Frit_Parm_Address_Table[type][4][chnl];
               if (result != 0 )
               {
                  result = (U_INT16)ReadEeprom(2+(U_INT8)pos, result, &maxflow);
                  OEMDetFritFlags[pos][chnl] |= (maxflow != 0 ) << (BIT8)type ;
               }
            }
         }
         else
         {
            OEMDetFritFlags[pos][chnl] = 0xffff ;
         }
      }
   }
}


/***********************************************************************/
/* FUNCTION: GetEepromInfo                                             */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Read CPF information from EEPROM and load information      */
/*          into globals                                               */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* LIMITATIONS:  none                                                  */
/*                                                                     */
/***********************************************************************/

static BIT8     Pneu_Bd_Present;

void GetEepromInfo ( void )
{

   /* check if pneumatics pcb is installed */
   if ((ZONES_CONFIG2 & PNEU_BD_PRESENT) == 0)
   {
      Pneu_Bd_Present = TRUE;
   }
   else
   {
      Pneu_Bd_Present = FALSE;
   }

   GetEepromCPFLabels();

#if 0
/* prom addr:     0FC.hi -> xIName[0]       0FC.lo -> xIName[1] ; if '[0]#0 then assumes active inlet name !!!         */
/* prom addr:     0FD.hi -> xIName[2]       0FD.lo -> xIName[3]                                                        */
/* prom addr:     0FE.hi -> xIName[4]       0FE.lo -> xIName[5]                                                        */

/* No eeprom location writes to xIName[6]; CPF intentions are that this is a "C" ascii trailer = 00H;                  */

/* xIName[0] =  00h to avoid activating CPF custom title logic                                                    FC.l */
/* xIName[1] =  time in .1 sec of VI filter equib delay; delay = 8*xIName[1]; 78H -> 96.0 sec                     FC.l */
/* xIName[2] =  Misc flags; '[2].0 =0/1 for VI_Direct "enforcement leak" disabled/enabled                         FD.h */
/*                          '[2].1 =0/1 to enable/force_to_zero "CalcSeptumPurgeReg" procedure output             FD.h */
/* xIName[3] =  VI filter rate; filter runs at 10Hz so 50H -> R=80 => 8.0 sec to equib to step input              FD.l */
/* xIName[4] =  VI flow setpt offset; high eight bits of 2's comp integer that is sign extended to 32 bit integer FE.h */
/* xIName[5] =  VI flow setpt offset; low  eight bits of 2's comp integer that is sign extended to 32 bit integer FE.l */
/* xIName[6] =  Available ( If comes in via FC.h and xIName[0]<=0, xIName[6]<=FC.h )                                   */

/* REVISIT !!!!!! these codes to END_REVISIT will be deleted for MFG. REL  */
   if ((BIName[0]==0) && (BIName[3]==0)) BIName[3] = 80 ; /* VI Flow Filter rate default */
   if ((BIName[0]==0) && (BIName[1]==0)) BIName[1] = 0x78 ; /* VI Flow Filter timing  default */
/* BIName[2]==1 && Active_Wkfile.Pneu.Back_Inlet.Injection_Mode==DIRECT => set split vnt OPEN to ensure vent is pluged */


   if ((FIName[0]==0) && (FIName[3]==0)) FIName[3] = 80 ; /* VI Flow Filter rate default */
   if ((FIName[0]==0) && (FIName[1]==0)) FIName[1] = 0x78 ; /* VI Flow Filter timing  default */
/* FIName[2]==1 && Active_Wkfile.Pneu.Frnt_Inlet.Injection_Mode==DIRECT => set split vnt OPEN to ensure vent is pluged */

/* END REVISIT */
#endif

   GetEepromCPFControls();
   GetEepromCPFThermal();
}



typedef struct
{
   U_INT16   module;
   U_INT16   address;
   BIT8     *value;
   U_INT16   size;
} READ_EEPROM_TABLE_TYPE;


static const READ_EEPROM_TABLE_TYPE Read_EEPROM_Table[] =
{
/* Module number, EEPROM read-from address, read-to address, and number of bytes */

  {FRNT_DETECTOR_MODULE_NUMBER,  OEM_GC_LABEL_ADDR, GCName,  OEM_GC_LABEL_SIZE },
  {BACK_DETECTOR_MODULE_NUMBER,  OEM_GC_LABEL_ADDR, GCName,  OEM_GC_LABEL_SIZE },

  {FRNT_INLET_MODULE_NUMBER, INLET_NAME_ADDR,       FIName,  INLET_NAME_SIZE},
/*{FRNT_INLET_MODULE_NUMBER, THERMAL_ADDR, (BIT8 *)&FIThermal[0], THERMAL_SIZE}, needless since no read ref's
                                                                                 See proc GetEepromCPFThermal */

  {BACK_INLET_MODULE_NUMBER, INLET_NAME_ADDR,       BIName,  INLET_NAME_SIZE},
/*{BACK_INLET_MODULE_NUMBER, THERMAL_ADDR, (BIT8 *)&BIThermal[0], THERMAL_SIZE}, needless since no read ref's
                                                                                 See proc GetEepromCPFThermal */


  /* Front detector */
  {FRNT_DETECTOR_MODULE_NUMBER, DET_NAME_ADDR,   FDName,        DET_NAME_SIZE  },

/*{FRNT_DETECTOR_MODULE_NUMBER,THERMAL_ADDR,(BIT8 *)&FDThermal[0],THERMAL_SIZE}, needless since no read ref's
                                                                                 See proc GetEepromCPFThermal */

  {FRNT_DETECTOR_MODULE_NUMBER, GAS1_LABEL_ADDR, FDGas1.label, GAS1_LABEL_SIZE},
  {FRNT_DETECTOR_MODULE_NUMBER, GAS2_LABEL_ADDR, FDGas2.label, GAS2_LABEL_SIZE},
  {FRNT_DETECTOR_MODULE_NUMBER, GAS3_LABEL_ADDR, FDGas3.label, GAS3_LABEL_SIZE},

  {FRNT_DETECTOR_MODULE_NUMBER, CTL1_LABEL_ADDR, FDCtl1.label, CTL1_LABEL_SIZE},
  {FRNT_DETECTOR_MODULE_NUMBER, CTL2_LABEL_ADDR, FDCtl2.label, CTL2_LABEL_SIZE},
  {FRNT_DETECTOR_MODULE_NUMBER, CTL3_LABEL_ADDR, FDCtl3.label, CTL3_LABEL_SIZE},
  {FRNT_DETECTOR_MODULE_NUMBER, CTL4_LABEL_ADDR, FDCtl4.label, CTL4_LABEL_SIZE},

  {FRNT_DETECTOR_MODULE_NUMBER, CTL5_LABEL_ADDR, FDCtrl5.label, CTL5_LABEL_SIZE},
  {FRNT_DETECTOR_MODULE_NUMBER, XTL6_LABEL_ADDR, FDXtrl6.label, XTL6_LABEL_SIZE},
  {FRNT_DETECTOR_MODULE_NUMBER, XTL7_LABEL_ADDR, FDXtrl7.label, XTL7_LABEL_SIZE},

  {FRNT_DETECTOR_MODULE_NUMBER, OEM_DIAG1_LABEL_ADDR,   FDDiag1.label,   OEM_DIAG1_LABEL_SIZE},
/*{FRNT_DETECTOR_MODULE_NUMBER, OEM_DIAG1_MULT_ADDR,  (BIT8 *) &FDDiag1.mult,    OEM_DIAG1_MULT_SIZE}, */
  {FRNT_DETECTOR_MODULE_NUMBER, OEM_DIAG1_OFFSET_ADDR, (BIT8 *)&FDDiag1.offset,  OEM_DIAG1_OFFSET_SIZE},

  {FRNT_DETECTOR_MODULE_NUMBER, OEM_DIAG2_LABEL_ADDR,   FDDiag2.label,   OEM_DIAG2_LABEL_SIZE},
/*{FRNT_DETECTOR_MODULE_NUMBER, OEM_DIAG2_MULT_ADDR,   (BIT8 *)&FDDiag2.mult,    OEM_DIAG2_MULT_SIZE}, */
  {FRNT_DETECTOR_MODULE_NUMBER, OEM_DIAG2_OFFSET_ADDR, (BIT8 *)&FDDiag2.offset,  OEM_DIAG2_OFFSET_SIZE},

  /* Back detector */
  {BACK_DETECTOR_MODULE_NUMBER, DET_NAME_ADDR,   BDName,        DET_NAME_SIZE},
/*{BACK_DETECTOR_MODULE_NUMBER,THERMAL_ADDR,(BIT8 *)&BDThermal[0],THERMAL_SIZE}, needless since no read ref's
                                                                                 See proc GetEepromCPFThermal */

  {BACK_DETECTOR_MODULE_NUMBER, GAS1_LABEL_ADDR, BDGas1.label, GAS1_LABEL_SIZE},
  {BACK_DETECTOR_MODULE_NUMBER, GAS2_LABEL_ADDR, BDGas2.label, GAS2_LABEL_SIZE},
  {BACK_DETECTOR_MODULE_NUMBER, GAS3_LABEL_ADDR, BDGas3.label, GAS3_LABEL_SIZE},

  {BACK_DETECTOR_MODULE_NUMBER, CTL1_LABEL_ADDR, BDCtl1.label, CTL1_LABEL_SIZE},
  {BACK_DETECTOR_MODULE_NUMBER, CTL2_LABEL_ADDR, BDCtl2.label, CTL2_LABEL_SIZE},
  {BACK_DETECTOR_MODULE_NUMBER, CTL3_LABEL_ADDR, BDCtl3.label, CTL3_LABEL_SIZE},
  {BACK_DETECTOR_MODULE_NUMBER, CTL4_LABEL_ADDR, BDCtl4.label, CTL4_LABEL_SIZE},

  {BACK_DETECTOR_MODULE_NUMBER, CTL5_LABEL_ADDR, BDCtrl5.label, CTL5_LABEL_SIZE},
  {BACK_DETECTOR_MODULE_NUMBER, XTL6_LABEL_ADDR, BDXtrl6.label, XTL6_LABEL_SIZE},
  {BACK_DETECTOR_MODULE_NUMBER, XTL7_LABEL_ADDR, BDXtrl7.label, XTL7_LABEL_SIZE},

  {BACK_DETECTOR_MODULE_NUMBER, OEM_DIAG1_LABEL_ADDR,   BDDiag1.label,   OEM_DIAG1_LABEL_SIZE},
/*{BACK_DETECTOR_MODULE_NUMBER, OEM_DIAG1_MULT_ADDR,   (BIT8 *)&BDDiag1.mult,    OEM_DIAG1_MULT_SIZE}, */
  {BACK_DETECTOR_MODULE_NUMBER, OEM_DIAG1_OFFSET_ADDR, (BIT8 *)&BDDiag1.offset,  OEM_DIAG1_OFFSET_SIZE},

  {BACK_DETECTOR_MODULE_NUMBER, OEM_DIAG2_LABEL_ADDR,   BDDiag2.label,   OEM_DIAG2_LABEL_SIZE},
/*{BACK_DETECTOR_MODULE_NUMBER, OEM_DIAG2_MULT_ADDR,   (BIT8 *)&BDDiag2.mult,    OEM_DIAG2_MULT_SIZE}, */
  {BACK_DETECTOR_MODULE_NUMBER, OEM_DIAG2_OFFSET_ADDR, (BIT8 *)&BDDiag2.offset,  OEM_DIAG2_OFFSET_SIZE}

};

#define F_DET_PTR &Inst_Status.Pneu.Frnt_Detector
#define B_DET_PTR &Inst_Status.Pneu.Back_Detector
#define READ_EEPROM_TABLE_SIZE sizeof(Read_EEPROM_Table)/sizeof(READ_EEPROM_TABLE_TYPE)
#define READ_EEPROM_TABLE_SIZE_L1 sizeof(Read_EEPROM_Table)/sizeof(READ_EEPROM_TABLE_TYPE)-1


static BIT8 SkipFrontGCName (void)
{
   U_INT16       type;
   U_INT16       pneutype;

   /* Use 1st Read_EEPROM_Table entry only if FD=OEM_AIB or FD=OEM_FID  and front_EPC_OEM pneu is present */
   type = (DISCRETE_IN1 & 0x0f) ;
   (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, TYPE, &pneutype);
   if (
       (
        ((DET_TYPE)type == OEM_AIB ) || ((DET_TYPE)type == OEM_FID )
       )
       &&
       (
         pneutype == ((U_INT16)AUX_MODULE)*256
       )
      )
   {
      return FALSE ;      /* this ENABLES getting GCName from front_det pneu eeprom */
   }
   else
   {
      return TRUE  ;      /* this SKIPS getting GCName from front_det pneu eeprom */
   }
}

static BIT8 SkipBackGCName (void)
{
   U_INT16       type;
   U_INT16       pneutype;

   /* Use 2nd Read_EEPROM_Table entry only if BD=OEM_AIB or BD=OEM_FID  and back_EPC_OEM pneu is present */
   type = ( DISCRETE_IN1 & 0xf0)>>4 ;
   (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, TYPE, &pneutype);
   if (
        0 == (
              (
               ((DET_TYPE)type == OEM_AIB ) || ((DET_TYPE)type == OEM_FID )
              )
              &&
              (
                pneutype == ((U_INT16)AUX_MODULE)*256
              )
             )
      )
   {
      return TRUE  ;  /* this SKIPS getting GCName from back_det pneu eeprom */
                      /* title from front will NOT be overwritten            */
   };

   (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, OEM_GC_LABEL_ADDR, &pneutype);

   if ( ( pneutype < 0x0200 ) || (pneutype > 0x7f7f ) )
   {
     return TRUE ; /* this SKIPS getting GCName from front_det pneu eeprom */
   }               /* title from front will NOT be overwritten             */

   return FALSE ; /* this ENABLES getting GCName from back_det pneu eeprom; title from front WILL be overwritten  */

}


/***********************************************************************/
/* FUNCTION: GetEepromCPFLabels                                        */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Read Label and CPF information from EEPROM and load        */
/*          information into globals                                   */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* LIMITATIONS:  none                                                  */
/*                                                                     */
/***********************************************************************/
static void GetEepromCPFLabels (void)
{
U_INT16       table_index;
U_INT16       size;
U_INT16      *pvalue;
U_INT16       cpf_pneu;

   /* get all titles and labels */

   for( table_index = 0; table_index < READ_EEPROM_TABLE_SIZE; table_index++)
   {
      if ((table_index == 0) && SkipFrontGCName() ) table_index++ ;
      if ((table_index == 1) && SkipBackGCName()  ) table_index++ ;

      /* cast to void used only to stop compiler warning */
      pvalue = (U_INT16 *)(void *)(Read_EEPROM_Table[table_index].value);
      for( size = 0; size < ((Read_EEPROM_Table[table_index].size/2)); size++)
      {
         if ( Pneu_Bd_Present && ModuleExists ( Read_EEPROM_Table[table_index].module ) )
         {
             (void)ReadEeprom( Read_EEPROM_Table[table_index].module,
                               Read_EEPROM_Table[table_index].address + size,
                               pvalue );
         }
         else
         {
             *pvalue = 0;
         }
         pvalue++;
      }
   }

   /* determine if this module should be treated as CPF */
   if ( Pneu_Bd_Present && ModuleExists ( FRNT_DETECTOR_MODULE_NUMBER ) )
   {
      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, CPF_PNEU_ADDR, &cpf_pneu);
      if(cpf_pneu)
      {
            FDCPF = TRUE;
      }
      else
      {
            FDCPF = FALSE;
      }
   }
   else
   {
      FDCPF = FALSE;
   }


   if ( Pneu_Bd_Present && ModuleExists ( BACK_DETECTOR_MODULE_NUMBER ) )
   {
      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, CPF_PNEU_ADDR, &cpf_pneu);
      if(cpf_pneu)
      {
            BDCPF = TRUE;
      }
      else
      {
            BDCPF = FALSE;
      }
   }
   else
   {
      BDCPF = FALSE;
   }

}

/***********************************************************************/
/* FUNCTION: GetEepromCPFControls                                      */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Read OIM control information from EEPROM and load          */
/*          information into globals                                   */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* LIMITATIONS:  none                                                  */
/*                                                                     */
/***********************************************************************/
static void GetEepromCPFControls (void)
{
U_INT16       fctl1_2_bits;
U_INT16       fctl3_4_bits;
U_INT16       bctl1_2_bits;
U_INT16       bctl3_4_bits;

#define FMT1          ((fctl1_2_bits & 0xe000)>>13)
#define NUM1          ((fctl1_2_bits & 0x1f00)>> 8)
#define FMT2          ((fctl1_2_bits & 0x00e0)>> 5)
#define NUM2          ((fctl1_2_bits & 0x001f)    )
#define FMT3          ((fctl3_4_bits & 0xe000)>>13)
#define NUM3          ((fctl3_4_bits & 0x1f00)>> 8)
#define FMT4          ((fctl3_4_bits & 0x00e0)>> 5)
#define NUM4          ((fctl3_4_bits & 0x001f)    )

/* CTL1_2 = |F1.2|F1.1|F1.0|N1.4|N1.3|N1.2|N1.1|N1.0|F2.2|F2.1|F2.0|N2.4|N2.3|N2.2|N2.1|N2.0|  */
/*           -------------- ------------------------ -------------- ------------------------   */
/*              Format_2          Numeric_2           Format_1         Numeric_1               */
/*                                                                                             */
/*          Format_N = 000/001   for numeric/on_off                                            */
/*          Numeric_N = 00000...01111 = number of bits in width if Format_N = 000              */
/*                                                                                             */
/*                                                                                             */
/*          Bits are assigned on the 16-pin cable to the OIM h/w starting with D0 ( 2^0 )      */
/*          All spares on the left. CTL3_4 is assigned the same way                            */
/*                                                                                             */
/*          CTL1_2 = CTL3_4 = 2121h -> 4 on/off controls in d3...d0                            */
/*                                                                                             */

   fctl1_2_bits = 0;
   fctl3_4_bits = 0;
   bctl1_2_bits = 0;
   bctl3_4_bits = 0;

   if ( Pneu_Bd_Present && ModuleExists ( FRNT_DETECTOR_MODULE_NUMBER ) )
   {
      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, CTL1_2_BITS_ADDR, &fctl1_2_bits);
      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, CTL3_4_BITS_ADDR, &fctl3_4_bits);

      FDCtl1.format = FMT1;
      FDCtl1.bits   = NUM1;
      FDCtl1.shift  = 0;
      FDCtl1.mask   = (((((U_INT32)1) << NUM1 ) -1 ) << FDCtl1.shift) & 0xffff;

      FDCtl2.format = FMT2;
      FDCtl2.bits   = NUM2;
      FDCtl2.shift  = FDCtl1.bits;
      FDCtl2.mask   = (((((U_INT32)1) << NUM2 ) -1 ) << FDCtl2.shift) & 0xffff;

      FDCtl3.format = FMT3;
      FDCtl3.bits   = NUM3;
      FDCtl3.shift  = FDCtl1.bits + FDCtl2.bits;
      FDCtl3.mask   = (((((U_INT32)1) << NUM3 ) -1 ) << FDCtl3.shift) & 0xffff;

      FDCtl4.format = FMT4;
      FDCtl4.bits   = NUM4;
      FDCtl4.shift  = FDCtl1.bits + FDCtl2.bits + FDCtl3.bits;
      FDCtl4.mask   = (((((U_INT32)1) << NUM4 ) -1 ) << FDCtl4.shift) & 0xffff;

      if ( FDCPF == FALSE)
      {
           (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, CTL1_2_PULSE_ADDR,       &fctl1_2_bits);
           (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, CTL3_4_PULSE_ADDR,       &fctl3_4_bits);
           (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, CTL5_PULSE_ADDR,         &bctl1_2_bits);

           FDCtl1.pulse_len  = (BIT8)( fctl1_2_bits & 0x00ff ) ;
           FDCtl2.pulse_len  = (BIT8)( fctl1_2_bits >> 8     ) ;
           FDCtl3.pulse_len  = (BIT8)( fctl3_4_bits & 0x00ff ) ;
           FDCtl4.pulse_len  = (BIT8)( fctl3_4_bits >> 8     ) ;
           FDCtrl5.pulse_len = (BIT8)( bctl1_2_bits & 0x00ff ) ;

           (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, OEM_DIAG1_MPY_DVD_ADDR,     &bctl3_4_bits);
           FDDiag1.mult      = (BIT8)(( bctl3_4_bits & 0xff00 ) >> 8 ) ;
           if (FDDiag1.mult==0) FDDiag1.mult = 1;
           FDDiag1.dvdr      = (BIT8)(( bctl3_4_bits & 0x00ff )      ) ;
           if (FDDiag1.dvdr==0) FDDiag1.dvdr = 1;

           (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, OEM_DIAG2_MPY_DVD_ADDR,     &bctl3_4_bits);
           FDDiag2.mult      = (BIT8)(( bctl3_4_bits & 0xff00 ) >> 8 ) ;
           if (FDDiag2.mult==0) FDDiag2.mult = 1;
           FDDiag2.dvdr      = (BIT8)(( bctl3_4_bits & 0x00ff )      ) ;
           if (FDDiag2.dvdr==0) FDDiag2.dvdr = 1;

           (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, OEM_RDY_DIAG_FILTER_ADDR,   &bctl3_4_bits);
           OEMPollTym[0]     = (BIT8)( bctl3_4_bits & 0x00ff ) ;
           FDDiag1.OldGain   = (BIT8)(( bctl3_4_bits & 0x0f00 ) >> 4 ) ;
           FDDiag2.OldGain   = (BIT8)(( bctl3_4_bits & 0xf000 ) >> 8 ) ;

      }

   }
   else
   {
      FDCtl1.format = 0;
      FDCtl1.bits   = 0;
      FDCtl1.shift  = 0;
      FDCtl1.mask   = 0;

      FDCtl2.format = 0;
      FDCtl2.bits   = 0;
      FDCtl2.shift  = 0;
      FDCtl2.mask   = 0;

      FDCtl3.format = 0;
      FDCtl3.bits   = 0;
      FDCtl3.shift  = 0;
      FDCtl3.mask   = 0;

      FDCtl4.format = 0;
      FDCtl4.bits   = 0;
      FDCtl4.shift  = 0;
      FDCtl4.mask   = 0;
   }


      /* remove unused values form a previous setting */

   if ( ( (DET_TYPE)(DISCRETE_IN1 & 0x0f) != OEM_AIB ) && ( (DET_TYPE)(DISCRETE_IN1 & 0x0f) != OEM_FID )  )
   {

      /* Since bits used on OIM i/f bit pack out from right end, the "unused bits" are
         all to the left side of the 16 bit output integer in the Active_Wkfile. Note
         that Active_Wkfile is pfail protected                                         */


      Active_Wkfile.det_cpf_ctl[FRONT].on_off =
          Active_Wkfile.det_cpf_ctl[FRONT].on_off &
              (( ((U_INT32)1) << (NUM1+NUM2+NUM3+NUM4) ) -1); /* zero out left most un-used */

      Active_Wkfile.det_cpf_ctl[FRONT].value =
          Active_Wkfile.det_cpf_ctl[FRONT].value &
              (( ((U_INT32)1) << (NUM1+NUM2+NUM3+NUM4) ) -1); /* zero out left most un-used */

   }


#undef NUM1
#undef FMT1
#undef NUM2
#undef FMT2
#undef NUM3
#undef FMT3
#undef NUM4
#undef FMT4

#define FMT1          ((bctl1_2_bits & 0xe000)>>13)
#define NUM1          ((bctl1_2_bits & 0x1f00)>> 8)
#define FMT2          ((bctl1_2_bits & 0x00e0)>> 5)
#define NUM2          ((bctl1_2_bits & 0x001f)    )
#define FMT3          ((bctl3_4_bits & 0xe000)>>13)
#define NUM3          ((bctl3_4_bits & 0x1f00)>> 8)
#define FMT4          ((bctl3_4_bits & 0x00e0)>> 5)
#define NUM4          ((bctl3_4_bits & 0x001f)    )


   if ( Pneu_Bd_Present && ModuleExists ( BACK_DETECTOR_MODULE_NUMBER ) )
   {
      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, CTL1_2_BITS_ADDR, &bctl1_2_bits);
      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, CTL3_4_BITS_ADDR, &bctl3_4_bits);


      BDCtl1.format = FMT1;
      BDCtl1.bits   = NUM1;
      BDCtl1.shift  = 0;
      BDCtl1.mask   = (((((U_INT32)1) << NUM1 ) -1 ) << BDCtl1.shift) & 0xffff;

      BDCtl2.format = FMT2;
      BDCtl2.bits   = NUM2;
      BDCtl2.shift  = BDCtl1.bits;
      BDCtl2.mask   = (((((U_INT32)1) << NUM2 ) -1 ) << BDCtl2.shift) & 0xffff;

      BDCtl3.format = FMT3;
      BDCtl3.bits   = NUM3;
      BDCtl3.shift  = BDCtl1.bits + BDCtl2.bits;
      BDCtl3.mask   = (((((U_INT32)1) << NUM3 ) -1 ) << BDCtl3.shift) & 0xffff;

      BDCtl4.format = FMT4;
      BDCtl4.bits   = NUM4;
      BDCtl4.shift  = BDCtl1.bits + BDCtl2.bits + BDCtl3.bits;
      BDCtl4.mask   = (((((U_INT32)1) << NUM4 ) -1 ) << BDCtl4.shift) & 0xffff;

      if ( BDCPF == FALSE)
      {
           (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, CTL1_2_PULSE_ADDR, &fctl1_2_bits);
           (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, CTL3_4_PULSE_ADDR, &fctl3_4_bits);
           (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, CTL5_PULSE_ADDR,   &bctl1_2_bits);

           BDCtl1.pulse_len  = (BIT8)( fctl1_2_bits & 0x00ff ) ;
           BDCtl2.pulse_len  = (BIT8)( fctl1_2_bits >> 8     ) ;
           BDCtl3.pulse_len  = (BIT8)( fctl3_4_bits & 0x00ff ) ;
           BDCtl4.pulse_len  = (BIT8)( fctl3_4_bits >> 8     ) ;
           BDCtrl5.pulse_len = (BIT8)( bctl1_2_bits & 0x00ff ) ;

           (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, OEM_DIAG1_MPY_DVD_ADDR,     &bctl3_4_bits);
           BDDiag1.mult      = (BIT8)(( bctl3_4_bits & 0xff00 ) >> 8 ) ;
           if (BDDiag1.mult==0) BDDiag1.mult = 1;
           BDDiag1.dvdr      = (BIT8)(( bctl3_4_bits & 0x00ff )      ) ;
           if (BDDiag1.dvdr==0) BDDiag1.dvdr = 1;

           (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, OEM_DIAG2_MPY_DVD_ADDR,     &bctl3_4_bits);
           BDDiag2.mult      = (BIT8)(( bctl3_4_bits & 0xff00 ) >> 8 ) ;
           if (BDDiag2.mult==0) BDDiag2.mult = 1;
           BDDiag2.dvdr      = (BIT8)(( bctl3_4_bits & 0x00ff )      ) ;
           if (BDDiag2.dvdr==0) BDDiag2.dvdr = 1;

           (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, OEM_RDY_DIAG_FILTER_ADDR,   &bctl3_4_bits);
           OEMPollTym[1]     = (BIT8)( bctl3_4_bits & 0x00ff ) ;
           BDDiag1.OldGain   = (BIT8)(( bctl3_4_bits & 0x0f00 ) >> 4 ) ;
           BDDiag2.OldGain   = (BIT8)(( bctl3_4_bits & 0xf000 ) >> 8 ) ;
      }

   }
   else
   {
      BDCtl1.format = 0;
      BDCtl1.bits   = 0;
      BDCtl1.shift  = 0;
      BDCtl1.mask   = 0;

      BDCtl2.format = 0;
      BDCtl2.bits   = 0;
      BDCtl2.shift  = 0;
      BDCtl2.mask   = 0;

      BDCtl3.format = 0;
      BDCtl3.bits   = 0;
      BDCtl3.shift  = 0;
      BDCtl3.mask   = 0;

      BDCtl4.format = 0;
      BDCtl4.bits   = 0;
      BDCtl4.shift  = 0;
      BDCtl4.mask   = 0;
   }

   if ( (((DISCRETE_IN1 & 0xf0)>>4 ) != (INT16)OEM_AIB) && (((DISCRETE_IN1 & 0xf0)>>4 ) != (INT16)OEM_FID)    )
   {
      /* remove unused values form a previous setting */
      Active_Wkfile.det_cpf_ctl[BACK].on_off =
          Active_Wkfile.det_cpf_ctl[BACK].on_off &
              (( ((U_INT32)1) << (NUM1+NUM2+NUM3+NUM4) ) -1);
      Active_Wkfile.det_cpf_ctl[BACK].value =
          Active_Wkfile.det_cpf_ctl[BACK].value &
              (( ((U_INT32)1) << (NUM1+NUM2+NUM3+NUM4) ) -1);
   }

}


/***********************************************************************/
/* FUNCTION: GetEepromCPFThermal                                       */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: Read thermal information from EEPROM and load              */
/*          information into globals                                   */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/* LIMITATIONS:  none                                                  */
/*                                                                     */
/***********************************************************************/
static void GetEepromCPFThermal (void)
{
U_INT16       thermal_word1_bits;
U_INT16       thermal_word2_bits;
U_INT16       thermal_word3_bits;
U_INT16       thermal_word4_bits;
U_INT16       thermal_word5_bits;
U_INT16       thermal_word6_bits;

   /* Read the thermal constants from the EEPROM */

#define PMULT          ((thermal_word1_bits & 0xff00)>> 8)
#define IMULT          ((thermal_word1_bits & 0x00ff)    )

#define DMULT          ((thermal_word2_bits & 0xff00)>> 8)
#define MINSTPT        ((thermal_word2_bits & 0x00ff)    )

#define RMPCOMP        ((thermal_word3_bits & 0xc000)>> 14)
#define MAXSTPT        ((thermal_word3_bits & 0x3fe0)>> 5)
#define SENSOR         ((thermal_word3_bits & 0x0018)>> 3)
#define CTLFREQ        ((thermal_word3_bits & 0x0007)    )

#define MAXRATE        ((thermal_word4_bits & 0x7ff0)>> 4)
#define CRYOCTL        ((thermal_word4_bits & 0x000e)>> 1)
#define THERMMOD       ((thermal_word4_bits & 0x0001)    )

#define PDIV           ((thermal_word5_bits & 0x7c00)>>10)
#define IDIV           ((thermal_word5_bits & 0x03e0)>> 5)
#define DDIV           ((thermal_word5_bits & 0x001f)    )

#define MINCTLERR      ((thermal_word6_bits & 0xf800)>>11)
#define MAXCTLERR      ((thermal_word6_bits & 0x07c0)>> 6)
#define MININTEG       ((thermal_word6_bits & 0x0038)>> 3)
#define MAXINTEG       ((thermal_word6_bits & 0x0007)    )


   if ( Pneu_Bd_Present && ModuleExists ( FRNT_DETECTOR_MODULE_NUMBER ) )
   {
      /* READ FRONT DETECTOR THERMAL CONFIGURATION */

      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, THERMAL_WORD1_ADDR, &thermal_word1_bits);
      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, THERMAL_WORD2_ADDR, &thermal_word2_bits);
      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, THERMAL_WORD3_ADDR, &thermal_word3_bits);
      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, THERMAL_WORD4_ADDR, &thermal_word4_bits);
      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, THERMAL_WORD5_ADDR, &thermal_word5_bits);
      (void)ReadEeprom(FRNT_DETECTOR_MODULE_NUMBER, THERMAL_WORD6_ADDR, &thermal_word6_bits);

      F_Det_Zone_Eeprom_Info.prop_mult =  PMULT;
      F_Det_Zone_Eeprom_Info.integ_mult = IMULT;

      F_Det_Zone_Eeprom_Info.deriv_mult  = DMULT;
      F_Det_Zone_Eeprom_Info.min_setpt = (MINSTPT==0)? NO_MINSTPT: MINSTPT-201;

      F_Det_Zone_Eeprom_Info.ramp_comp = RMPCOMP;
      F_Det_Zone_Eeprom_Info.max_setpt = MAXSTPT;
      F_Det_Zone_Eeprom_Info.sensor_type = SENSOR;
      F_Det_Zone_Eeprom_Info.control_freq = CTLFREQ;

      F_Det_Zone_Eeprom_Info.max_rate = (MAXRATE == 0)? NO_MAXRATE: MAXRATE-1;
      F_Det_Zone_Eeprom_Info.cryo_control_type = CRYOCTL;
      F_Det_Zone_Eeprom_Info.therm_config_mod = THERMMOD;

      F_Det_Zone_Eeprom_Info.prop_div = PDIV;
      F_Det_Zone_Eeprom_Info.integ_div = IDIV;
      F_Det_Zone_Eeprom_Info.deriv_div = DDIV;

      F_Det_Zone_Eeprom_Info.min_control_error = (MINCTLERR==0)? NO_MINCTLERR: MINCTLERR-32;
      F_Det_Zone_Eeprom_Info.max_control_error = MAXCTLERR;
      F_Det_Zone_Eeprom_Info.min_integ_power = MININTEG;
      F_Det_Zone_Eeprom_Info.max_integ_power = MAXINTEG;
   }
   else
   {
      F_Det_Zone_Eeprom_Info.prop_mult =  0;
      F_Det_Zone_Eeprom_Info.integ_mult = 0;

      F_Det_Zone_Eeprom_Info.deriv_mult  = 0;
      F_Det_Zone_Eeprom_Info.min_setpt = NO_MINSTPT;

      F_Det_Zone_Eeprom_Info.ramp_comp = 0;
      F_Det_Zone_Eeprom_Info.max_setpt = 0;
      F_Det_Zone_Eeprom_Info.sensor_type = 0;
      F_Det_Zone_Eeprom_Info.control_freq = 0;

      F_Det_Zone_Eeprom_Info.max_rate = NO_MAXRATE;
      F_Det_Zone_Eeprom_Info.cryo_control_type = 0;
      F_Det_Zone_Eeprom_Info.therm_config_mod = 0;

      F_Det_Zone_Eeprom_Info.prop_div = 0;
      F_Det_Zone_Eeprom_Info.integ_div = 0;
      F_Det_Zone_Eeprom_Info.deriv_div = 0;

      F_Det_Zone_Eeprom_Info.min_control_error = NO_MINCTLERR;
      F_Det_Zone_Eeprom_Info.max_control_error = 0;
      F_Det_Zone_Eeprom_Info.min_integ_power = 0;
      F_Det_Zone_Eeprom_Info.max_integ_power = 0;
   }



   if ( Pneu_Bd_Present && ModuleExists ( BACK_DETECTOR_MODULE_NUMBER ) )
   {
      /* READ BACK DETECTOR THERMAL CONFIGURATION */

      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, THERMAL_WORD1_ADDR, &thermal_word1_bits);
      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, THERMAL_WORD2_ADDR, &thermal_word2_bits);
      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, THERMAL_WORD3_ADDR, &thermal_word3_bits);
      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, THERMAL_WORD4_ADDR, &thermal_word4_bits);
      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, THERMAL_WORD5_ADDR, &thermal_word5_bits);
      (void)ReadEeprom(BACK_DETECTOR_MODULE_NUMBER, THERMAL_WORD6_ADDR, &thermal_word6_bits);

      B_Det_Zone_Eeprom_Info.prop_mult =  PMULT;
      B_Det_Zone_Eeprom_Info.integ_mult = IMULT;

      B_Det_Zone_Eeprom_Info.deriv_mult  = DMULT;
      B_Det_Zone_Eeprom_Info.min_setpt = (MINSTPT==0)? NO_MINSTPT: MINSTPT-201;

      B_Det_Zone_Eeprom_Info.ramp_comp = RMPCOMP;
      B_Det_Zone_Eeprom_Info.max_setpt = MAXSTPT;
      B_Det_Zone_Eeprom_Info.sensor_type = SENSOR;
      B_Det_Zone_Eeprom_Info.control_freq = CTLFREQ;

      B_Det_Zone_Eeprom_Info.max_rate = (MAXRATE == 0)? NO_MAXRATE: MAXRATE-1;
      B_Det_Zone_Eeprom_Info.cryo_control_type = CRYOCTL;
      B_Det_Zone_Eeprom_Info.therm_config_mod = THERMMOD;

      B_Det_Zone_Eeprom_Info.prop_div = PDIV;
      B_Det_Zone_Eeprom_Info.integ_div = IDIV;
      B_Det_Zone_Eeprom_Info.deriv_div = DDIV;

      B_Det_Zone_Eeprom_Info.min_control_error = (MINCTLERR==0)? NO_MINCTLERR: MINCTLERR-32;
      B_Det_Zone_Eeprom_Info.max_control_error = MAXCTLERR;
      B_Det_Zone_Eeprom_Info.min_integ_power = MININTEG;
      B_Det_Zone_Eeprom_Info.max_integ_power = MAXINTEG;
   }
   else
   {
      B_Det_Zone_Eeprom_Info.prop_mult =  0;
      B_Det_Zone_Eeprom_Info.integ_mult = 0;

      B_Det_Zone_Eeprom_Info.deriv_mult  = 0;
      B_Det_Zone_Eeprom_Info.min_setpt = NO_MINSTPT;

      B_Det_Zone_Eeprom_Info.ramp_comp = 0;
      B_Det_Zone_Eeprom_Info.max_setpt = 0;
      B_Det_Zone_Eeprom_Info.sensor_type = 0;
      B_Det_Zone_Eeprom_Info.control_freq = 0;

      B_Det_Zone_Eeprom_Info.max_rate = NO_MAXRATE;
      B_Det_Zone_Eeprom_Info.cryo_control_type = 0;
      B_Det_Zone_Eeprom_Info.therm_config_mod = 0;

      B_Det_Zone_Eeprom_Info.prop_div = 0;
      B_Det_Zone_Eeprom_Info.integ_div = 0;
      B_Det_Zone_Eeprom_Info.deriv_div = 0;

      B_Det_Zone_Eeprom_Info.min_control_error = NO_MINCTLERR;
      B_Det_Zone_Eeprom_Info.max_control_error = 0;
      B_Det_Zone_Eeprom_Info.min_integ_power = 0;
      B_Det_Zone_Eeprom_Info.max_integ_power = 0;
   }


   if ( Pneu_Bd_Present && ModuleExists ( FRNT_INLET_MODULE_NUMBER ) )
   {
      /* READ FRONT INLET THERMAL CONFIGURATION */

      (void)ReadEeprom(FRNT_INLET_MODULE_NUMBER, THERMAL_WORD1_ADDR, &thermal_word1_bits);
      (void)ReadEeprom(FRNT_INLET_MODULE_NUMBER, THERMAL_WORD2_ADDR, &thermal_word2_bits);
      (void)ReadEeprom(FRNT_INLET_MODULE_NUMBER, THERMAL_WORD3_ADDR, &thermal_word3_bits);
      (void)ReadEeprom(FRNT_INLET_MODULE_NUMBER, THERMAL_WORD4_ADDR, &thermal_word4_bits);
      (void)ReadEeprom(FRNT_INLET_MODULE_NUMBER, THERMAL_WORD5_ADDR, &thermal_word5_bits);
      (void)ReadEeprom(FRNT_INLET_MODULE_NUMBER, THERMAL_WORD6_ADDR, &thermal_word6_bits);

      F_Inlet_Zone_Eeprom_Info.prop_mult =  PMULT;
      F_Inlet_Zone_Eeprom_Info.integ_mult = IMULT;

      F_Inlet_Zone_Eeprom_Info.deriv_mult  = DMULT;
      F_Inlet_Zone_Eeprom_Info.min_setpt = (MINSTPT==0)? NO_MINSTPT: MINSTPT-201;

      F_Inlet_Zone_Eeprom_Info.ramp_comp = RMPCOMP;
      F_Inlet_Zone_Eeprom_Info.max_setpt = MAXSTPT;
      F_Inlet_Zone_Eeprom_Info.sensor_type = SENSOR;
      F_Inlet_Zone_Eeprom_Info.control_freq = CTLFREQ;

      F_Inlet_Zone_Eeprom_Info.max_rate = (MAXRATE == 0)? NO_MAXRATE: MAXRATE-1;
      F_Inlet_Zone_Eeprom_Info.cryo_control_type = CRYOCTL;
      F_Inlet_Zone_Eeprom_Info.therm_config_mod = THERMMOD;

      F_Inlet_Zone_Eeprom_Info.prop_div = PDIV;
      F_Inlet_Zone_Eeprom_Info.integ_div = IDIV;
      F_Inlet_Zone_Eeprom_Info.deriv_div = DDIV;

      F_Inlet_Zone_Eeprom_Info.min_control_error = (MINCTLERR==0)? NO_MINCTLERR: MINCTLERR-32;
      F_Inlet_Zone_Eeprom_Info.max_control_error = MAXCTLERR;
      F_Inlet_Zone_Eeprom_Info.min_integ_power = MININTEG;
      F_Inlet_Zone_Eeprom_Info.max_integ_power = MAXINTEG;
   }
   else
   {
      F_Inlet_Zone_Eeprom_Info.prop_mult =  0;
      F_Inlet_Zone_Eeprom_Info.integ_mult = 0;

      F_Inlet_Zone_Eeprom_Info.deriv_mult  = 0;
      F_Inlet_Zone_Eeprom_Info.min_setpt = NO_MINSTPT;

      F_Inlet_Zone_Eeprom_Info.ramp_comp = 0;
      F_Inlet_Zone_Eeprom_Info.max_setpt = 0;
      F_Inlet_Zone_Eeprom_Info.sensor_type = 0;
      F_Inlet_Zone_Eeprom_Info.control_freq = 0;

      F_Inlet_Zone_Eeprom_Info.max_rate = NO_MAXRATE;
      F_Inlet_Zone_Eeprom_Info.cryo_control_type = 0;
      F_Inlet_Zone_Eeprom_Info.therm_config_mod = 0;

      F_Inlet_Zone_Eeprom_Info.prop_div = 0;
      F_Inlet_Zone_Eeprom_Info.integ_div = 0;
      F_Inlet_Zone_Eeprom_Info.deriv_div = 0;

      F_Inlet_Zone_Eeprom_Info.min_control_error = NO_MINCTLERR;
      F_Inlet_Zone_Eeprom_Info.max_control_error = 0;
      F_Inlet_Zone_Eeprom_Info.min_integ_power = 0;
      F_Inlet_Zone_Eeprom_Info.max_integ_power = 0;
   }


   if ( Pneu_Bd_Present && ModuleExists ( BACK_INLET_MODULE_NUMBER ) )
   {
      /* READ BACK INLET THERMAL CONFIGURATION */

      (void)ReadEeprom(BACK_INLET_MODULE_NUMBER, THERMAL_WORD1_ADDR, &thermal_word1_bits);
      (void)ReadEeprom(BACK_INLET_MODULE_NUMBER, THERMAL_WORD2_ADDR, &thermal_word2_bits);
      (void)ReadEeprom(BACK_INLET_MODULE_NUMBER, THERMAL_WORD3_ADDR, &thermal_word3_bits);
      (void)ReadEeprom(BACK_INLET_MODULE_NUMBER, THERMAL_WORD4_ADDR, &thermal_word4_bits);
      (void)ReadEeprom(BACK_INLET_MODULE_NUMBER, THERMAL_WORD5_ADDR, &thermal_word5_bits);
      (void)ReadEeprom(BACK_INLET_MODULE_NUMBER, THERMAL_WORD6_ADDR, &thermal_word6_bits);

      B_Inlet_Zone_Eeprom_Info.prop_mult =  PMULT;
      B_Inlet_Zone_Eeprom_Info.integ_mult = IMULT;

      B_Inlet_Zone_Eeprom_Info.deriv_mult  = DMULT;
      B_Inlet_Zone_Eeprom_Info.min_setpt = (MINSTPT==0)? NO_MINSTPT: MINSTPT-201;

      B_Inlet_Zone_Eeprom_Info.ramp_comp = RMPCOMP;
      B_Inlet_Zone_Eeprom_Info.max_setpt = MAXSTPT;
      B_Inlet_Zone_Eeprom_Info.sensor_type = SENSOR;
      B_Inlet_Zone_Eeprom_Info.control_freq = CTLFREQ;

      B_Inlet_Zone_Eeprom_Info.max_rate = (MAXRATE == 0)? NO_MAXRATE: MAXRATE-1;
      B_Inlet_Zone_Eeprom_Info.cryo_control_type = CRYOCTL;
      B_Inlet_Zone_Eeprom_Info.therm_config_mod = THERMMOD;

      B_Inlet_Zone_Eeprom_Info.prop_div = PDIV;
      B_Inlet_Zone_Eeprom_Info.integ_div = IDIV;
      B_Inlet_Zone_Eeprom_Info.deriv_div = DDIV;

      B_Inlet_Zone_Eeprom_Info.min_control_error = (MINCTLERR==0)? NO_MINCTLERR: MINCTLERR-32;
      B_Inlet_Zone_Eeprom_Info.max_control_error = MAXCTLERR;
      B_Inlet_Zone_Eeprom_Info.min_integ_power = MININTEG;
      B_Inlet_Zone_Eeprom_Info.max_integ_power = MAXINTEG;
   }
   else
   {
      B_Inlet_Zone_Eeprom_Info.prop_mult =  0;
      B_Inlet_Zone_Eeprom_Info.integ_mult = 0;

      B_Inlet_Zone_Eeprom_Info.deriv_mult  = 0;
      B_Inlet_Zone_Eeprom_Info.min_setpt = NO_MINSTPT;

      B_Inlet_Zone_Eeprom_Info.ramp_comp = 0;
      B_Inlet_Zone_Eeprom_Info.max_setpt = 0;
      B_Inlet_Zone_Eeprom_Info.sensor_type = 0;
      B_Inlet_Zone_Eeprom_Info.control_freq = 0;

      B_Inlet_Zone_Eeprom_Info.max_rate = NO_MAXRATE;
      B_Inlet_Zone_Eeprom_Info.cryo_control_type = 0;
      B_Inlet_Zone_Eeprom_Info.therm_config_mod = 0;

      B_Inlet_Zone_Eeprom_Info.prop_div = 0;
      B_Inlet_Zone_Eeprom_Info.integ_div = 0;
      B_Inlet_Zone_Eeprom_Info.deriv_div = 0;

      B_Inlet_Zone_Eeprom_Info.min_control_error = NO_MINCTLERR;
      B_Inlet_Zone_Eeprom_Info.max_control_error = 0;
      B_Inlet_Zone_Eeprom_Info.min_integ_power = 0;
      B_Inlet_Zone_Eeprom_Info.max_integ_power = 0;
   }

}

/***********************************************************************/
/* FUNCTION:  ClearThermalEepromModified                               */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  The therm_config_mod parameter should be set when the     */
/*      EEPROM is programmed.  This function clears the parameter      */
/*      in the data structor and clears the bit in the EEPROM.         */
/*                                                                     */
/* RETURNED VALUE:  None                                               */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/


void ClearThermalEepromModified( U_INT16 module_number )
{
   U_INT16 thermal_word4_bits;

   if ( (!Pneu_Bd_Present) || (ModuleExists(module_number) == 0) )  /* if module not there .... */
   {
      return;
   }

   (void)ReadEeprom(module_number, THERMAL_WORD4_ADDR, &thermal_word4_bits);

   /* clear modified bit */
   thermal_word4_bits = thermal_word4_bits & 0xFFFE;

   /* write to eeprom */
   (void)WriteEeprom(module_number, THERMAL_WORD4_ADDR, thermal_word4_bits);

   /* write to thermal data structure */
   switch(module_number)
   {
      case  FRNT_INLET_MODULE_NUMBER:
         F_Inlet_Zone_Eeprom_Info.therm_config_mod = 0;
         break;
      case  BACK_INLET_MODULE_NUMBER:
         B_Inlet_Zone_Eeprom_Info.therm_config_mod = 0;
         break;
      case  FRNT_DETECTOR_MODULE_NUMBER:
         F_Det_Zone_Eeprom_Info.therm_config_mod = 0;
         break;
      case  BACK_DETECTOR_MODULE_NUMBER:
         B_Det_Zone_Eeprom_Info.therm_config_mod = 0;
         break;
   }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void PneuStartup(void)

/**end_proto**/
{

     U_INT16 tasks;

     if ((ZONES_CONFIG2 & PNEU_BD_PRESENT) == 0)
     { /* pcb is really there */

        if ( Inst_Status.Pneu.Pneu_Dsp_Alive == FALSE )  return;

        if ( PF_Reset )
        {
            SetPneuDefaultSetpts();
        }

        /* see if we have any thing to do, if we do, put up a message */
        tasks = 0;
        if ( EpcInlet( &Inst_Status.Pneu.Frnt_Inlet ) )       tasks++;
        if ( EpcInlet( &Inst_Status.Pneu.Back_Inlet ) )       tasks++;
        if ( EpcDetector( &Inst_Status.Pneu.Frnt_Detector ) ) tasks++;
        if ( EpcDetector( &Inst_Status.Pneu.Back_Detector ) ) tasks++;
        if ( PneuAuxPresent() )                               tasks++;

        if ( tasks != 0 )
        {
            /* Paint Initialize Pneumatics message */

#ifndef mccabe
#ifndef MSC
            #pragma ASM
            xref   M.INIT_PNEU
            xref   Display
            lea.l  (M.INIT_PNEU).l,A0
            jsr    Display
            #pragma END_ASM
#endif
#endif

            if ( tasks <= 2 )
            {
                 /* delay a few seconds so the message can be read */
/*--------------changed by wangwei---------------*/
//                 for ( tasks = 0 ; tasks < 1024 ; tasks++ ) WAIT_FOR_512_TO_RISE;
               sleep(2);
/*-------------end change by wangwei--------------*/
            }
        }


        if ( EpcInlet( &Inst_Status.Pneu.Frnt_Inlet ) )
        {
             BuildThermistorTable ( Inst_Status.Pneu.Frnt_Inlet.Module_Number,
                                   &Inst_Status.Pneu.Frnt_Inlet.Tcomp_Tables->Thermistor );
             DoInletTComp( &Inst_Status.Pneu.Frnt_Inlet );
             LoadInletCalib ( &Inst_Status.Pneu.Frnt_Inlet );
               /* inlet Pids are dependant on sensor values, and must be done last */
             DownloadInletPids ( &Inst_Status.Pneu.Frnt_Inlet );
        }
        else
        {
             BuildDefaultThermistorTable( &Inst_Status.Pneu.Frnt_Inlet.Tcomp_Tables->Thermistor );
        }

        if ( EpcInlet( &Inst_Status.Pneu.Back_Inlet ) )
        {
             BuildThermistorTable ( Inst_Status.Pneu.Back_Inlet.Module_Number,
                                   &Inst_Status.Pneu.Back_Inlet.Tcomp_Tables->Thermistor );
             DoInletTComp( &Inst_Status.Pneu.Back_Inlet );
             LoadInletCalib ( &Inst_Status.Pneu.Back_Inlet );
               /* inlet Pids are dependant on sensor values, and must be done last */
             DownloadInletPids ( &Inst_Status.Pneu.Back_Inlet );
        }
        else
        {
             BuildDefaultThermistorTable( &Inst_Status.Pneu.Back_Inlet.Tcomp_Tables->Thermistor );
        }

        if ( EpcDetector( &Inst_Status.Pneu.Frnt_Detector ) )
        {
            ReadDetGasMaxFlowRates ( &Inst_Status.Pneu.Frnt_Detector );
            GetGas_2MinFlowRate ( &Inst_Status.Pneu.Frnt_Detector, Inst_Status.Pneu.Frnt_Detector.Module_Number );
            BuildThermistorTable ( Inst_Status.Pneu.Frnt_Detector.Module_Number,
                                   &Inst_Status.Pneu.Frnt_Detector.Tcomp_Tables->Thermistor );
            DoDetCompTables ( &Inst_Status.Pneu.Frnt_Detector );
            LoadDetCalib ( &Inst_Status.Pneu.Frnt_Detector );
            DownloadDetPids ( &Inst_Status.Pneu.Frnt_Detector );
        }
        else
        {
             BuildDefaultThermistorTable( &Inst_Status.Pneu.Frnt_Detector.Tcomp_Tables->Thermistor );
        }

        if ( EpcDetector( &Inst_Status.Pneu.Back_Detector ) )
        {
            ReadDetGasMaxFlowRates ( &Inst_Status.Pneu.Back_Detector );
            GetGas_2MinFlowRate ( &Inst_Status.Pneu.Back_Detector,Inst_Status.Pneu.Back_Detector.Module_Number );
            BuildThermistorTable ( Inst_Status.Pneu.Back_Detector.Module_Number,
                                   &Inst_Status.Pneu.Back_Detector.Tcomp_Tables->Thermistor );
            DoDetCompTables ( &Inst_Status.Pneu.Back_Detector );
            LoadDetCalib ( &Inst_Status.Pneu.Back_Detector );
            DownloadDetPids ( &Inst_Status.Pneu.Back_Detector );
        }
        else
        {
             BuildDefaultThermistorTable( &Inst_Status.Pneu.Back_Detector.Tcomp_Tables->Thermistor );
        }

        if ( PneuAuxPresent() )
        {
            BuildThermistorTable ( Inst_Status.Pneu.Aux.Module_Number,
                                   &Inst_Status.Pneu.Aux.Tcomp_Tables->Thermistor );
            DoAuxCompTables ( &Inst_Status.Pneu.Aux );
            LoadAuxCalib ( &Inst_Status.Pneu.Aux );
            DownloadAuxPids ( &Inst_Status.Pneu.Aux.Aux_3 );
            DownloadAuxPids ( &Inst_Status.Pneu.Aux.Aux_4 );
            DownloadAuxPids ( &Inst_Status.Pneu.Aux.Aux_5 );
        }
        else
        {
             BuildDefaultThermistorTable( &Inst_Status.Pneu.Aux.Tcomp_Tables->Thermistor );
        }

        /* revisit : only to support late boot of pneumatics.  When */
        /* pneumatics boots before interrupts, these can be removed */
        DetGasTypeChanged( DET_POSITION ( &Inst_Status.Pneu.Frnt_Detector ));
        DetGasTypeChanged( DET_POSITION ( &Inst_Status.Pneu.Back_Detector ));


        Inst_Status.Pneu.Restarted_Channel_Mask = 0;
        Inst_Status.Pneu.Channels_Reported_Shutdown = 0;

        (void)RestartAllChannels();

        ReconfigurePneu();

        SetupPneuRamps();

        InitializeEnvironment();

     }
     else
     {

        /* update the iu-scaling and dcm2_per_iu fields */
        /* so we do not get divide by zero in the flow  */
        /* setpt calculator                             */

        InitPneuStatus();

        MakeThisADirtball();

        ReconfigurePneu();
     }

     Inst_Status.Pneu.Pneu_Alive = TRUE;  /* we're up! */

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 PneuKeyShortcutEnabled( void )

/**end_proto**/
{
   return Inst_Config.Pneu.Shortcut_Enabled;
}

/**begin_proto**/

void TestPneuKeyShortcut( void )

/**end_proto**/
{
#if 0     /* remove for Vireo, this doesn't work */
     U_INT32  test_word = 0xffff;

     if ( ((ZONES_CONFIG2 & PNEU_BD_PRESENT) == 0) &&
          !TestForException ( PNEU_FPGA_FAULT )   &&
          !TestForException ( DEAD_PCB )         )  /* pcb is really there */
     {

        /* if test bit is pulled low, enable shortcut to pneu_keys */

        if ( !PcbPeek( 0x3010, &test_word ) )
        {
            test_word = 0xffff;
        }
     }

     Inst_Config.Pneu.Shortcut_Enabled =  (( test_word & 0x0400 ) == 0 );
#endif

     Inst_Config.Pneu.Shortcut_Enabled =  FALSE;
}



/**begin_proto**/

U_INT16 GetCurrentOvenTemp ( void )

/**end_proto**/
{
    if ( Use_Thermal_Setpt )
    {
        return Oven_Table.temp_setpt;
    }
    else
    {
        return Oven_Table.zone_temp >> 8;
    }
}

/**begin_proto**/

U_INT16 GetOvenInitTemp ( void )

/**end_proto**/
{
    return GetRampInitValue( &Oven_Temp_Info );
}
